-- get raja state local game = require("main_state") local timer_util = require("timer_util") local judgeY = 992 local judgeX = 30 local judgeOffset = 40 local judgeFontHeight = 36 local grooveX = 660 local grooveY = 650 local speechBubbleX = 1600 local speechBubbleY = 374 local speechBubbleFontHeight = 30 local jacketWindowY = 200 local jacketWindowX = 1000 function Append(list, t) if t then for i, v in pairs(t) do table.insert(list, v) end end end local function getDiff(op) local diff = tonumber(game.number(op)) if diff < 0 then return diff end return "+" .. diff end -- thanks mr mary local function getClearType() local cleartype = { [0] = "PASSED", [1] = "FAILED", [2] = "A-CLEAR", [3] = "LA-CLEAR", [4] = "EASY CLEAR", [5] = "CLEAR", [6] = "HARD CLEAR", [7] = "EXH CLEAR", [8] = "FC", [9] = "PERFECT", [10] = "MAX" } -- clear id return cleartype[game.number(370)] end local function isBestClear() -- target clear < current clear if game.number(371) < game.number(370) then return "(BEST)" else return "" end end -- thanks mr mary local function getRank() local rank = { [1] = "AAA", [2] = "AA", [3] = "A", [4] = "B", [5] = "C", [6] = "D", [7] = "E", [8] = "F" } local gradeOptionIdx = 0 repeat gradeOptionIdx = gradeOptionIdx + 1 until game.option(299 + gradeOptionIdx) return rank[gradeOptionIdx] end local function isBestRank() local nowRank = 0 local bestRank = 0 repeat nowRank = nowRank + 1 until game.option(299 + nowRank) repeat bestRank = bestRank + 1 until game.option(319 + bestRank) -- counter-intuitive, but AAA is 0, and F is 8 -- so whichever stops earlier is win if bestRank > nowRank then return "(BEST)" else return "" end end local function getIrRank() return game.number(179) end local function getIrTotal() return game.number(180) end local function constructIrRankDisplay() return game.text(1020) .. ": " .. getIrRank() .. " / " .. getIrTotal() end local header = { -- type = result type = 7, name = "win95 result 0.1a", -- skin size w = 1920, h = 1080, -- scene timer scene = 3600000, -- time until inputs are active input = 500, -- time it takes to fade out fadeout = 100, -- me :D author = "boons", -- config options filepath = { { name = "CLEAR", path = "customize/bg/clear/*.png", def = "_Default.png", category = "CLEAR" }, { name = "FAIL", path = "customize/bg/fail/*.png", def = "BSOD.png", category = "FAIL" }, { name = "CLIPPY", path = "customize/clippy/*.png", def = "Clippy.png", category = "CLIPPY" } }, category = { { name = "RESULT BG", item = { "CLEAR", "FAIL" } }, { name = "CLIPPY", item = { "CLIPPY" } } } } local function main() local skin = {} -- add header properties into skin for k, v in pairs(header) do skin[k] = v end -- tell raja where to look for assets skin.source = { { id = 0, path = "customize/bg/fail/*.png" }, { id = 1, path = "customize/bg/clear/*.png" }, { id = 2, path = "asset/song-data.png" }, { id = 3, path = "asset/groove-gauge.png" }, { id = 4, path = "asset/clippy-bubble.png" }, { id = 5, path = "customize/clippy/*.png" }, { id = 6, path = "asset/jacket.png" }, { id = 7, path = "asset/taskbar.png" }, { id = 8, path = "asset/time-container.png" } -- todo: taskbar items } skin.font = { { id = 0, path = "font/SarasaMonoCL-Regular.ttf" }, -- CJK monospace { id = 1, path = "font/Windows_Regular.ttf" } -- clippy speech } skin.image = { { id = "bg_clear", src = 1, x = 0, y = 0, w = -1, h = -1 }, { id = "bg_failed", src = 0, x = 0, y = 0, w = -1, h = -1 }, { id = "bg_song", src = 2, x = 0, y = 0, w = -1, h = -1 }, { id = "bg_groove", src = 3, x = 0, y = 0, w = -1, h = -1 }, { id = "clippy_speechbubble", src = 4, x = 0, y = 0, w = -1, h = -1 }, { id = "clippy_character", src = 5, x = 0, y = 0, w = -1, h = -1 }, { id = "jacket_window", src = 6, x = 0, y = 0, w = -1, h = -1 }, { id = "taskbar", src = 7, x = 0, y = 0, w = -1, h = -1 }, { id = "taskbar_time", src = 8, x = 0, y = 0, w = -1, h = -1 } } skin.text = { { id = "text_groove_title", font = 0, size = 40, align = 0, overflow = 1, constantText = "GAUGE: " .. game.number(107) .. "." .. game.number(407) .. "%" }, -- gauge { id = "text_title", font = 0, size = 40, align = 0, overflow = 2, ref = 12 }, -- shrink { id = "text_level", font = 0, size = 40, align = 0, overflow = 1, ref = 1002 }, { id = "pgreat", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "PERFECT: " .. game.number(110) }, { id = "great", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "GREAT : " .. game.number(111) }, { id = "good", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "GOOD : " .. game.number(112) }, { id = "bad", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "BAD : " .. game.number(113) }, { id = "poor", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "POOR : " .. game.number(114) }, { id = "expoor", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "EXPOOR : " .. game.number(420) }, { id = "exscore", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "SCORE : " .. game.number(171) }, { id = "exscore_diff", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "BEST : " .. getDiff(172) }, { id = "exscore_diff_target", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "TARGET : " .. getDiff(153) }, -- judge rank { id = "total_fast", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "FAST : " .. game.number(423) }, { id = "total_slow", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "SLOW : " .. game.number(424) }, -- clippy { id = "clippy_rank", font = 1, size = 60, align = 0, overflow = 1, constantText = getRank() }, { id = "clippy_rank_best", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = isBestRank() }, { id = "clippy_clear_type", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = getClearType() }, { id = "clippy_clear_type_best", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = isBestClear() }, { id = "clippy_rate", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = "RATE: " .. game.number(155) .. "." .. game.number(156) .. "%" }, -- ir { id = "clippy_ir_rank", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, value = constructIrRankDisplay }, { id = "clippy_ir_unavailable", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = "IR OFFLINE (^^);" }, --jacket { id = "text_jacket_title", font = 0, size = 40, align = 0, overflow = 1, constantText = "JACKET" }, { id = "jacket_no_jacket", font = 0, size = 52, align = 1, overflow = 1, constantText = "NO JACKET (^^);" }, -- task bar { id = "taskbar_time_text", font = 1, size = 40, align = 0, overflow = 1, constantText = os.date("%c") } } -- gauge graph skin.gaugegraph = { { id = "gauge_line", assistClearLineColor = "FF00FF00", assistAndEasyFailLineColor = "00ff0000", grooveFailLineColor = "00ffff00", grooveClearAndHardLineColor = "ff000000", exHardLineColor = "ffff0000", hazardLineColor = "cccccc00", borderlineColor = "ff000000" }, { id = "gauge_bg", assistClearBGColor = "ff00ff00", assistAndEasyFailBGColor = "00ff0000", grooveFailBGColor = "00ffff00", grooveClearAndHardBGColor = "ff000000", exHardBGColor = "ffff0000", hazardBGColor = "44444400", borderColor = "eeeeee00" }, } -- put it all to use skin.destination = { { id = "bg_clear", op = { 90 }, -- cleared dst = { { x = 0, y = 0, w = 1920, h = 1080, a = 255, filter = 1 } } }, { id = "bg_failed", op = { 91 }, -- failed dst = { { x = 0, y = 0, w = 1920, h = 1080, a = 255, filter = 1 } } } } local songdata = require("dst.songdata") local clippy = require("dst.clippy") local gauge = require("dst.gauge") local jacket = require("dst.jacket") local taskbar = require("dst.taskbar") Append(skin.destination, songdata.getSongData(judgeX, judgeY, judgeFontHeight, judgeOffset)) Append(skin.destination, clippy.getClippy(speechBubbleX, speechBubbleY, speechBubbleFontHeight)) Append(skin.destination, gauge.getGauge(grooveX, grooveY)) Append(skin.destination, jacket.getJacket(jacketWindowX, jacketWindowY)) Append(skin.destination, taskbar.getTaskbar()) return skin end return { header = header, main = main }