diff --git a/scripts/result.lua b/scripts/result.lua index 1725c93..408f885 100644 --- a/scripts/result.lua +++ b/scripts/result.lua @@ -34,7 +34,7 @@ local gradeImages = { A = gfx.CreateSkinImage("common/grades/A.png", 0), B = gfx.CreateSkinImage("common/grades/B.png", 0), C = gfx.CreateSkinImage("common/grades/C.png", 0), - D = gfx.CreateSkinImage("common/grades/D.png", 0), + D = gfx.CreateSkinImage("common/grades/D.png", 0) } local gaugeTypeBadgeImages = { @@ -43,15 +43,21 @@ local gaugeTypeBadgeImages = { gfx.CreateSkinImage("result/gauge_type_badges/permissive.png", 0), gfx.CreateSkinImage("result/gauge_type_badges/effective.png", 0), -- TODO: add blastive gfx.CreateSkinImage("result/gauge_type_badges/effective.png", 0), -- placeholders in case other types get added - gfx.CreateSkinImage("result/gauge_type_badges/effective.png", 0), + gfx.CreateSkinImage("result/gauge_type_badges/effective.png", 0) } -local gaugeEffFailFillImage = gfx.CreateSkinImage("gameplay/gauges/effective/gauge_fill_fail.png", 0) -local gaugeEffPassFillImage = gfx.CreateSkinImage("gameplay/gauges/effective/gauge_fill_pass.png", 0) -local gaugeExcFillImage = gfx.CreateSkinImage("gameplay/gauges/excessive/gauge_fill.png", 0) -local gaugePermFillImage = gfx.CreateSkinImage("gameplay/gauges/permissive/gauge_fill.png", 0) -local gaugeBlastiveFillImage = gfx.CreateSkinImage("gameplay/gauges/blastive/gauge_fill.png", 0) - +local gaugeEffFailFillImage = gfx.CreateSkinImage( + "gameplay/gauges/effective/gauge_fill_fail.png", + 0) +local gaugeEffPassFillImage = gfx.CreateSkinImage( + "gameplay/gauges/effective/gauge_fill_pass.png", + 0) +local gaugeExcFillImage = gfx.CreateSkinImage( + "gameplay/gauges/excessive/gauge_fill.png", 0) +local gaugePermFillImage = gfx.CreateSkinImage( + "gameplay/gauges/permissive/gauge_fill.png", 0) +local gaugeBlastiveFillImage = gfx.CreateSkinImage( + "gameplay/gauges/blastive/gauge_fill.png", 0) local difficultyLabelImages = { gfx.CreateSkinImage("diff/1 novice.png", 0), @@ -61,7 +67,7 @@ local difficultyLabelImages = { gfx.CreateSkinImage("diff/5 infinite.png", 0), gfx.CreateSkinImage("diff/6 gravity.png", 0), gfx.CreateSkinImage("diff/7 heavenly.png", 0), - gfx.CreateSkinImage("diff/8 vivid.png", 0), + gfx.CreateSkinImage("diff/8 vivid.png", 0) } local clearBadgeImages = { @@ -71,11 +77,11 @@ local clearBadgeImages = { gfx.CreateSkinImage("result/clears/COMPLETE.png", 0), gfx.CreateSkinImage("result/clears/UC.png", 0), gfx.CreateSkinImage("result/clears/PUC.png", 0), - gfx.CreateSkinImage("result/clears/AUTOPLAY.png", 0), + gfx.CreateSkinImage("result/clears/AUTOPLAY.png", 0) } -- ANIMS -local idolAnimation = gfx.LoadSkinAnimation('idol', 1/30, 0, true); +local idolAnimation = gfx.LoadSkinAnimation('idol', 1 / 30, 0, true); local transitionEnterScale = 0; local idolAnimTransitionScale = 0; @@ -134,15 +140,15 @@ end function drawTimingBar(y, value, max, type) gfx.BeginPath(); - if type == 'crit' then - gfx.FillColor(253,243,24,255); + if type == 'crit' then + gfx.FillColor(253, 243, 24, 255); elseif type == 'early' then - gfx.FillColor(215,48,182,255); + gfx.FillColor(215, 48, 182, 255); elseif type == 'late' then - gfx.FillColor(46,211,241,255); + gfx.FillColor(46, 211, 241, 255); end - gfx.Rect(rightPanelX+696,rightPanelY+y,293*(value/max), 8); + gfx.Rect(rightPanelX + 696, rightPanelY + y, 293 * (value / max), 8); gfx.Fill(); gfx.ClosePath(); end @@ -150,51 +156,50 @@ end function load_number_image(path) local images = {} for i = 0, 9 do - images[i + 1] = gfx.CreateSkinImage(string.format("%s/%d.png", path, i), 0) + images[i + 1] = gfx.CreateSkinImage(string.format("%s/%d.png", path, i), + 0) end return images end function draw_number(x, y, alpha, num, digits, images, is_dim, scale, kern) scale = scale or 1; - kern = kern or 1; - local tw, th = gfx.ImageSize(images[1]) - tw = tw * scale; - th = th * scale; + kern = kern or 1; + local tw, th = gfx.ImageSize(images[1]) + tw = tw * scale; + th = th * scale; x = x + (tw * (digits - 1)) / 2 y = y - th / 2 for i = 1, digits do local mul = 10 ^ (i - 1) local digit = math.floor(num / mul) % 10 local a = alpha - if is_dim and num < mul then - a = 0.4 - end + if is_dim and num < mul then a = 0.4 end gfx.BeginPath() gfx.ImageRect(x, y, tw, th, images[digit + 1], a, 0) x = x - (tw * kern) end end -local drawIdol = function (deltaTime) +local drawIdol = function(deltaTime) local idolAnimTickRes = gfx.TickAnimation(idolAnimation, deltaTime); - if idolAnimTickRes == 1 then - gfx.GlobalAlpha(idolAnimTransitionScale); + if idolAnimTickRes == 1 then + gfx.GlobalAlpha(idolAnimTransitionScale); - idolAnimTransitionScale = idolAnimTransitionScale + 1/60; - if (idolAnimTransitionScale > 1) then - idolAnimTransitionScale = 1; - end + idolAnimTransitionScale = idolAnimTransitionScale + 1 / 60; + if (idolAnimTransitionScale > 1) then + idolAnimTransitionScale = 1; + end - gfx.ImageRect(0, 0, desw, desh, idolAnimation, 1, 0); - gfx.GlobalAlpha(1); - end + gfx.ImageRect(0, 0, desw, desh, idolAnimation, 1, 0); + gfx.GlobalAlpha(1); + end end local drawTopBar = function() gfx.BeginPath(); local tw, th = gfx.ImageSize(topBarImage); - th = (desw/tw)*th; -- recalculate the height of the bar to scale it down + th = (desw / tw) * th; -- recalculate the height of the bar to scale it down gfx.ImageRect(0, -th * (1 - Easing.outQuad(transitionEnterScale)), desw, th, topBarImage, 1, 0); @@ -211,20 +216,19 @@ local scoreNumber = load_number_image("score_num"); local drawRightPanelContent = function() local highScoreScore = 0; - if highScore then - highScoreScore = highScore.score - end + if highScore then highScoreScore = highScore.score end local highScoreDelta = result.score - highScoreScore -- Draw clear badge - local badgeImage = clearBadgeImages[result.badge+1] or clearBadgeImages[1] + local badgeImage = clearBadgeImages[result.badge + 1] or clearBadgeImages[1] if (result.autoplay) then badgeImage = clearBadgeImages[7]; -- Display AUTOPLAY badge end local tw, th = gfx.ImageSize(badgeImage); gfx.BeginPath(); - gfx.ImageRect(rightPanelX+1140-tw, rightPanelY-10, tw*0.85, th*0.85, badgeImage, 1, 0); + gfx.ImageRect(rightPanelX + 1140 - tw, rightPanelY - 10, tw * 0.85, + th * 0.85, badgeImage, 1, 0); -- Draw song name and artist gfx.FontSize(28) @@ -233,20 +237,24 @@ local drawRightPanelContent = function() gfx.Text(result.artist, rightPanelX + 435, rightPanelY + 143); -- Draw score - draw_number(rightPanelX+580, rightPanelY+192, 1.0, math.floor(result.score / 10000), 4, scoreNumber, true, 0.40, 1.12) - draw_number(rightPanelX+775, rightPanelY+200, 1.0, result.score, 4, scoreNumber, true, 0.25, 1.12) + draw_number(rightPanelX + 580, rightPanelY + 192, 1.0, + math.floor(result.score / 10000), 4, scoreNumber, true, 0.40, + 1.12) + draw_number(rightPanelX + 775, rightPanelY + 200, 1.0, result.score, 4, + scoreNumber, true, 0.25, 1.12) -- If this is the highscore, draw over the glowing best badge - if highScoreDelta > 0 then + if highScoreDelta > 0 then gfx.BeginPath(); - gfx.ImageRect(rightPanelX+364, rightPanelY+167, 97, 53, bestScoreBadgeImage, 1, 0); + gfx.ImageRect(rightPanelX + 364, rightPanelY + 167, 97, 53, + bestScoreBadgeImage, 1, 0); end -- Draw grade local gradeImageKey = string.gsub(result.grade, '+', '_P'); local gradeImage = gradeImages[gradeImageKey] or gradeImages.D gfx.BeginPath(); - gfx.ImageRect(rightPanelX+890, rightPanelY+130, 85, 85, gradeImage, 1, 0); + gfx.ImageRect(rightPanelX + 890, rightPanelY + 130, 85, 85, gradeImage, 1, 0); -- Draw best score gfx.FontSize(20) @@ -254,22 +262,23 @@ local drawRightPanelContent = function() gfx.LoadSkinFont('Digital-Serial-Bold.ttf') local deltaPrefix = '-' - if highScoreDelta > 0 then - deltaPrefix = '+' - end + if highScoreDelta > 0 then deltaPrefix = '+' end highScoreDelta = math.abs(highScoreDelta); - gfx.Text(string.format("%08d", highScoreScore), rightPanelX + 962, rightPanelY + 239); - gfx.Text(deltaPrefix .. string.format("%08d", highScoreDelta), rightPanelX + 962, rightPanelY + 259); - + gfx.Text(string.format("%08d", highScoreScore), rightPanelX + 962, + rightPanelY + 239); + gfx.Text(deltaPrefix .. string.format("%08d", highScoreDelta), + rightPanelX + 962, rightPanelY + 259); -- Draw gauge type badge gfx.BeginPath(); - gfx.ImageRect(rightPanelX+722, rightPanelY+273, 211, 40, gaugeTypeBadgeImages[result.gauge_type + 1], 1, 0); + gfx.ImageRect(rightPanelX + 722, rightPanelY + 273, 211, 40, + gaugeTypeBadgeImages[result.gauge_type + 1], 1, 0); -- Draw gauge % gfx.FontSize(24) - gfx.Text(math.floor(result.gauge * 100) .. '%', rightPanelX + 984, rightPanelY + 295); + gfx.Text(math.floor(result.gauge * 100) .. '%', rightPanelX + 984, + rightPanelY + 295); -- Draw gauge fill local gaugeFillImage = gaugeEffPassFillImage; @@ -292,35 +301,35 @@ local drawRightPanelContent = function() gaugeFillImage = gaugeBlastiveFillImage; end - local gaugePosX = rightPanelX+1027; - local gaugePosY = rightPanelY+309; + local gaugePosX = rightPanelX + 1027; + local gaugePosY = rightPanelY + 309; local FillW, FillH = 9, 236; gfx.BeginPath(); - gfx.Scissor(gaugePosX, gaugePosY+(FillH-(FillH*(result.gauge))), FillW, FillH*(result.gauge)) + gfx.Scissor(gaugePosX, gaugePosY + (FillH - (FillH * (result.gauge))), + FillW, FillH * (result.gauge)) gfx.ImageRect(gaugePosX, gaugePosY, FillW, FillH, gaugeFillImage, 1, 0); gfx.ResetScissor(); - -- Draw the breakpoint line if needed if (gaugeBreakpoint > 0) then gfx.Save() - gfx.BeginPath() + gfx.BeginPath() gfx.GlobalAlpha(0.75); - local lineY = gaugePosY+(FillH-(FillH*(gaugeBreakpoint))) - - gfx.MoveTo(gaugePosX, lineY) - gfx.LineTo(gaugePosX+10, lineY) + local lineY = gaugePosY + (FillH - (FillH * (gaugeBreakpoint))) - gfx.StrokeWidth(2) - gfx.StrokeColor(255,255,255) - gfx.Stroke() + gfx.MoveTo(gaugePosX, lineY) + gfx.LineTo(gaugePosX + 10, lineY) + + gfx.StrokeWidth(2) + gfx.StrokeColor(255, 255, 255) + gfx.Stroke() gfx.ClosePath() - gfx.Restore() + gfx.Restore() end - + -- Draw err/early/critical/late/err texts gfx.Text(earlyLateBarsStats.earlyErrors, rightPanelX + 683, @@ -353,13 +362,17 @@ local drawRightPanelContent = function() gfx.Text(objectTypeTimingStats.chip.errors, rightPanelX + 255, rightPanelY + 425); -- LONG - gfx.Text(objectTypeTimingStats.long.criticals, rightPanelX + 333, rightPanelY + 365); + gfx.Text(objectTypeTimingStats.long.criticals, rightPanelX + 333, + rightPanelY + 365); gfx.Text('-', rightPanelX + 333, rightPanelY + 395); - gfx.Text(objectTypeTimingStats.long.errors, rightPanelX + 333, rightPanelY + 425); + gfx.Text(objectTypeTimingStats.long.errors, rightPanelX + 333, + rightPanelY + 425); -- VOL - gfx.Text(objectTypeTimingStats.vol.criticals, rightPanelX + 411, rightPanelY + 365); + gfx.Text(objectTypeTimingStats.vol.criticals, rightPanelX + 411, + rightPanelY + 365); gfx.Text('-', rightPanelX + 411, rightPanelY + 395); - gfx.Text(objectTypeTimingStats.vol.errors, rightPanelX + 411, rightPanelY + 425); + gfx.Text(objectTypeTimingStats.vol.errors, rightPanelX + 411, + rightPanelY + 425); -- Draw max combo gfx.Text(result.maxCombo, rightPanelX + 371, rightPanelY + 466); @@ -369,49 +382,50 @@ local drawBottomPanel = function() gfx.BeginPath(); local tw, th = gfx.ImageSize(bottomPanelImage); - gfx.ImageRect(bottomPanelX, bottomPanelY, tw, th, - bottomPanelImage, 1, 0); + gfx.ImageRect(bottomPanelX, bottomPanelY, tw, th, bottomPanelImage, 1, 0); end -local drawBottomPanelContent = function (deltatime) +local drawBottomPanelContent = function(deltatime) -- Draw appeal card gfx.BeginPath(); - gfx.ImageRect(bottomPanelX+58, bottomPanelY+277, 103, 132, appealCardImage, 1, 0); + gfx.ImageRect(bottomPanelX + 58, bottomPanelY + 277, 103, 132, + appealCardImage, 1, 0); -- Draw description gfx.FontSize(22) gfx.LoadSkinFont('Digital-Serial-Bold.ttf') gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE) - gfx.Text('Hellooooooo', bottomPanelX+190, bottomPanelY+282); + gfx.Text('Hellooooooo', bottomPanelX + 190, bottomPanelY + 282); -- Draw username gfx.FontSize(28) - gfx.Text(username, bottomPanelX+190, bottomPanelY+314); + gfx.Text(username, bottomPanelX + 190, bottomPanelY + 314); -- Draw dan badge gfx.BeginPath(); - gfx.ImageRect(bottomPanelX+187, bottomPanelY+362, 107, 29, danBadgeImage, 1, 0); - + gfx.ImageRect(bottomPanelX + 187, bottomPanelY + 362, 107, 29, + danBadgeImage, 1, 0); + -- Draw volforce - VolforceWindow.render(0, bottomPanelX+310, bottomPanelY+355) + VolforceWindow.render(0, bottomPanelX + 310, bottomPanelY + 355) -- Draw IR text gfx.FontSize(22) - gfx.Text(irText, bottomPanelX+80, bottomPanelY+461); + gfx.Text(irText, bottomPanelX + 80, bottomPanelY + 461); -- Draw median and mean hit delta - local leftX = bottomPanelX+600 - local rightX = bottomPanelX+1010 - local baseY = bottomPanelY+440 + local leftX = bottomPanelX + 600 + local rightX = bottomPanelX + 1010 + local baseY = bottomPanelY + 440 local detailTextMargin = 25 gfx.FontSize(20) gfx.Text('Median hit delta', leftX, baseY); - gfx.Text('Mean hit delta', leftX, baseY+detailTextMargin); - + gfx.Text('Mean hit delta', leftX, baseY + detailTextMargin); + gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT + gfx.TEXT_ALIGN_MIDDLE) gfx.Text(result.medianHitDelta, rightX, baseY); - gfx.Text(result.meanHitDelta, rightX, baseY+detailTextMargin); + gfx.Text(result.meanHitDelta, rightX, baseY + detailTextMargin); end local drawJacketPanel = function() @@ -423,15 +437,18 @@ end local drawJacketPanelContent = function() gfx.BeginPath(); - gfx.ImageRect(jacketPanelX + 12, jacketPanelY + 26, 273, 273, jacketImage or defaultJacketImage, 1, 0); + gfx.ImageRect(jacketPanelX + 12, jacketPanelY + 26, 273, 273, + jacketImage or defaultJacketImage, 1, 0); gfx.BeginPath(); - gfx.ImageRect(jacketPanelX + 188, jacketPanelY + 3, 140/1.5, 31/1.5, difficultyLabelImages[result.difficulty+1] or difficultyLabelImages[4], 1, 0); + gfx.ImageRect(jacketPanelX + 188, jacketPanelY + 3, 140 / 1.5, 31 / 1.5, + difficultyLabelImages[result.difficulty + 1] or + difficultyLabelImages[4], 1, 0); gfx.FontSize(17) gfx.LoadSkinFont('Digital-Serial-Bold.ttf') gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT + gfx.TEXT_ALIGN_MIDDLE) - gfx.Text(result.level, jacketPanelX+270, jacketPanelY+14.5); + gfx.Text(result.level, jacketPanelX + 270, jacketPanelY + 14.5); end local IR_HeartbeatResponse = function(res) @@ -462,7 +479,7 @@ local tickTransitions = function(deltaTime) (1 - Easing.outQuad(transitionEnterScale))) bottomPanelY = 1170 + (BOTTOM_PANEL_TRANSTION_ENTER_OFFSET * - (1 - Easing.outQuad(transitionEnterScale))) + (1 - Easing.outQuad(transitionEnterScale))) jacketPanelX = 40 + (JACKET_PANEL_TRANSTION_ENTER_OFFSET * (1 - Easing.outQuad(transitionEnterScale))) @@ -473,59 +490,93 @@ result_set = function() jacketImage = gfx.CreateImage(result.jacketPath, 0) end + -- Reset stats + earlyLateBarsStats = { + earlyErrors = 0, + earlyNears = 0, + criticals = 0, + lateNears = 0, + lateErrors = 0 + }; + objectTypeTimingStats = { + chip = {criticals = 0, nears = 0, errors = 0}, + long = {criticals = 0, errors = 0}, + vol = {criticals = 0, errors = 0} + } + -- Store the highest score so we can use it later for delta and stuff highScore = result.highScores[1]; - -- "CHIP" objects - for hitStatIndex = 1, #result.noteHitStats do - local hitStat = result.noteHitStats[hitStatIndex]; + -- This check is to prevent errors when these are not available + if (result.noteHitStats and result.holdHitStats and result.laserHitStats) then + -- "CHIP" objects + for hitStatIndex = 1, #result.noteHitStats do + local hitStat = result.noteHitStats[hitStatIndex]; - if (hitStat.rating == 0) then -- Errors - objectTypeTimingStats.chip.errors = objectTypeTimingStats.chip.errors + 1; + if (hitStat.rating == 0) then -- Errors + objectTypeTimingStats.chip.errors = + objectTypeTimingStats.chip.errors + 1; - if hitStat.delta < 0 then - earlyLateBarsStats.earlyErrors = earlyLateBarsStats.earlyErrors + 1; - else - earlyLateBarsStats.lateErrors = earlyLateBarsStats.lateErrors + 1; + if hitStat.delta < 0 then + earlyLateBarsStats.earlyErrors = + earlyLateBarsStats.earlyErrors + 1; + else + earlyLateBarsStats.lateErrors = + earlyLateBarsStats.lateErrors + 1; + end + elseif hitStat.rating == 1 then -- Nears + objectTypeTimingStats.chip.nears = + objectTypeTimingStats.chip.nears + 1; + + if hitStat.delta < 0 then + earlyLateBarsStats.earlyNears = + earlyLateBarsStats.earlyNears + 1; + else + earlyLateBarsStats.lateNears = + earlyLateBarsStats.lateNears + 1; + end + else -- Criticals + objectTypeTimingStats.chip.criticals = + objectTypeTimingStats.chip.criticals + 1; end - elseif hitStat.rating == 1 then -- Nears - objectTypeTimingStats.chip.nears = objectTypeTimingStats.chip.nears + 1; + end - if hitStat.delta < 0 then - earlyLateBarsStats.earlyNears = earlyLateBarsStats.earlyNears + 1; - else - earlyLateBarsStats.lateNears = earlyLateBarsStats.lateNears + 1; + -- "LONG" objects + for hitStatIndex = 1, #result.holdHitStats do + local hitStat = result.holdHitStats[hitStatIndex]; + + if (hitStat.rating == 0) then -- Errors + objectTypeTimingStats.long.errors = + objectTypeTimingStats.long.errors + 1; + earlyLateBarsStats.lateErrors = + earlyLateBarsStats.lateErrors + 1; + else -- Criticals + objectTypeTimingStats.long.criticals = + objectTypeTimingStats.long.criticals + 1; end - else -- Criticals - objectTypeTimingStats.chip.criticals = objectTypeTimingStats.chip.criticals + 1; end - end + -- "VOL" a.k.a laser objects + for hitStatIndex = 1, #result.laserHitStats do + local hitStat = result.laserHitStats[hitStatIndex]; - - -- "LONG" objects - for hitStatIndex = 1, #result.holdHitStats do - local hitStat = result.holdHitStats[hitStatIndex]; - - if (hitStat.rating == 0) then -- Errors - objectTypeTimingStats.long.errors = objectTypeTimingStats.long.errors + 1; - earlyLateBarsStats.lateErrors = earlyLateBarsStats.lateErrors + 1; - else -- Criticals - objectTypeTimingStats.long.criticals = objectTypeTimingStats.long.criticals + 1; + if (hitStat.rating == 0) then -- Errors + objectTypeTimingStats.vol.errors = + objectTypeTimingStats.vol.errors + 1; + earlyLateBarsStats.lateErrors = + earlyLateBarsStats.lateErrors + 1; + else -- Criticals + objectTypeTimingStats.vol.criticals = + objectTypeTimingStats.vol.criticals + 1; + end end - end - - -- "VOL" a.k.a laser objects - for hitStatIndex = 1, #result.laserHitStats do - local hitStat = result.laserHitStats[hitStatIndex]; - - if (hitStat.rating == 0) then -- Errors - objectTypeTimingStats.vol.errors = objectTypeTimingStats.vol.errors + 1; - earlyLateBarsStats.lateErrors = earlyLateBarsStats.lateErrors + 1; - else -- Criticals - objectTypeTimingStats.vol.criticals = objectTypeTimingStats.vol.criticals + 1; - end + else + objectTypeTimingStats = { + chip = {criticals = 'N/A', nears = 'N/A', errors = 'N/A'}, + long = {criticals = 'N/A', errors = 'N/A'}, + vol = {criticals = 'N/A', errors = 'N/A'} + } end earlyLateBarsStats.criticals = result.perfects -- Criticals are for all objects @@ -568,8 +619,8 @@ render = function(deltaTime, showStats) gfx.FontSize(18) gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_TOP) -- gfx.Text('DELTA: ' .. deltaTime .. ' // TRANSITION_ENTER_SCALE: ' .. - -- transitionEnterScale .. ' // EASING_OUT_QUAD: ' .. - -- Easing.outQuad(transitionEnterScale), 8, 8); + -- transitionEnterScale .. ' // EASING_OUT_QUAD: ' .. + -- Easing.outQuad(transitionEnterScale), 8, 8); tickTransitions(deltaTime) gfx.Restore();