diff --git a/Themes/Til Death/BGAnimations/ScreenEvaluation decorations/default.lua b/Themes/Til Death/BGAnimations/ScreenEvaluation decorations/default.lua index 125c55a42f..46c560e90a 100644 --- a/Themes/Til Death/BGAnimations/ScreenEvaluation decorations/default.lua +++ b/Themes/Til Death/BGAnimations/ScreenEvaluation decorations/default.lua @@ -809,11 +809,105 @@ local function scoreBoard(pn, position) end t[#t+1] = jc + -- Boolean to check whether shift or alt/backslash is held + local shiftHeld = false + local altHeld = false + + t[#t+1] = Def.ActorFrame { + OnCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(function(event) + -- Detect if first or repeated shift press + local button = event.DeviceInput.button + if button == "DeviceButton_left shift" or button == "DeviceButton_right shift" or button == "DeviceButton_tab" then + if event.type == "InputEventType_FirstPress" or event.type == "InputEventType_Repeat" then + if not shiftHeld then + shiftHeld = true + MESSAGEMAN:Broadcast("ShiftPressed") + end + elseif event.type == "InputEventType_Release" then + if shiftHeld then + shiftHeld = false + MESSAGEMAN:Broadcast("ShiftReleased") + end + end + elseif button == "DeviceButton_left alt" or button == "DeviceButton_right alt" or button == "DeviceButton_backslash" then + if event.type == "InputEventType_FirstPress" or event.type == "InputEventType_Repeat" then + if not altHeld then + altHeld = true + MESSAGEMAN:Broadcast("AltPressed") + end + elseif event.type == "InputEventType_Release" then + if altHeld then + altHeld = false + MESSAGEMAN:Broadcast("AltReleased") + end + end + end + end) + end + } + + -- Function for calculating RA and LA, returns the ratio of ridiculous to marvelous and ludicrous to ridiculous from offset plot in replay. + local function calculateRatios(score) + -- Get replay depending on whether custom windows were used or not + local replay = usingCustomWindows and REPLAYS:GetActiveReplay() or score:GetReplay() + replay:LoadAllData() + -- Offset and tap note vectors from replay + local offsetTable = replay:GetOffsetVector() + local typeTable = replay:GetTapNoteTypeVector() + + if not offsetTable or #offsetTable == 0 or not typeTable or #typeTable == 0 then + return -1, -1, -1 + end + + -- Define judgement windows + local window = usingCustomWindows and getCurrentCustomWindowConfigJudgmentWindowTable() or { + TapNoteScore_W1 = 22.5 * ms.JudgeScalers[judge], -- j4 marv + TapNoteScore_W2 = 45 * ms.JudgeScalers[judge], -- j4 perf + TapNoteScore_W3 = 90 * ms.JudgeScalers[judge], -- j4 g + } + -- Define RA and LA thresholds + window["TapNoteScore_W0"] = window["TapNoteScore_W1"] / 2 -- ra threshold + window["TapNoteScore_W-1"] = window["TapNoteScore_W0"] / 2 -- la threshold + + local laThreshold = window["TapNoteScore_W-1"] + local raThreshold = window["TapNoteScore_W0"] + local marvThreshold = window["TapNoteScore_W1"] -- marv + + local ludic = 0 + local ridicLA = 0 + local ridic = 0 + local marvRA = 0 + + -- Iterate over offset table + for i, o in ipairs(offsetTable) do + -- Check if note is tap or hold + if typeTable[i] == "TapNoteType_Tap" or typeTable[i] == "TapNoteType_HoldHead" then + local off = math.abs(o) + if off <= raThreshold then + ridic = ridic + 1 + elseif off <= marvThreshold then + marvRA = marvRA + 1 + end + if off <= laThreshold then + ludic = ludic + 1 + elseif off <= raThreshold then + ridicLA = ridicLA + 1 + end + end + end + + -- Return ratios, ridic count, and marv count + local ridiculousAttack = ridic / marvRA + local ludicrousAttack = ludic / ridicLA + return ridiculousAttack, ludicrousAttack, ridicLA, marvRA + end + --[[ - The following section first adds the ratioText and the maRatio. Then the paRatio is added and positioned. The right - values for maRatio and paRatio are then filled in. Finally ratioText and maRatio are aligned to paRatio. + The following section first adds the ratioText, laRatio, raRatio, maRatio, and paRatio. Then the correct values are filled in. + When shift or alt/backslash is held, the display changes accordingly. --]] - local ratioText, maRatio, paRatio, marvelousTaps, perfectTaps, greatTaps + local ratioText, raRatio, laRatio, maRatio, paRatio, marvelousTaps, perfectTaps, greatTaps t[#t+1] = Def.ActorFrame { Name = "MAPARatioContainer", @@ -825,6 +919,24 @@ local function scoreBoard(pn, position) self:zoom(0.25):halign(1) end }, + LoadFont("Common Large") .. { + Name = "LAText", + InitCommand = function(self) + laRatio = self + self:settextf("%.2f:1", 0) + self:zoom(0.25):halign(1):rainbow() -- Rainbow cuz it's LA man come on + self:visible(false) + end + }, + LoadFont("Common Large") .. { + Name = "RAText", + InitCommand = function(self) + raRatio = self + self:settextf("%.2f:1", 0) + self:zoom(0.25):halign(1) -- No color, user can set whatever they want here. AAAAA is white so I left as white + self:visible(false) + end + }, LoadFont("Common Large") .. { Name = "MAText", InitCommand = function(self) @@ -847,32 +959,88 @@ local function scoreBoard(pn, position) self:playcommand("Set") end, SetCommand = function(self) - - -- Fill in maRatio and paRatio + -- Fill in raRatio, laRatio, maRatio, and paRatio + local ridiculousAttack, ludicrousAttack, ridics, marvs = calculateRatios(score) maRatio:settextf("%.1f:1", marvelousTaps / perfectTaps) paRatio:settextf("%.1f:1", perfectTaps / greatTaps) + raRatio:settextf("%.2f:1", ridiculousAttack) + laRatio:settextf("%.2f:1", ludicrousAttack) + + -- Align with where paRatio was and move things accordingly + if altHeld then + -- Show LA/RA ratios + laRatio:visible(true) + raRatio:visible(true) + maRatio:visible(false) + paRatio:visible(false) + + raRatio:settextf("%.2f:1", ridics / marvs) -- ridic:marv + raRatio:xy(paRatio:GetX(), paRatio:GetY()) + local laRatioX = raRatio:GetX() - raRatio:GetZoomedWidth() - 10 + laRatio:xy(laRatioX, raRatio:GetY()) + local ratioTextX = laRatioX - laRatio:GetZoomedWidth() - 10 + ratioText:xy(ratioTextX, raRatio:GetY()) + + ratioText:settextf("LA/RA ratio:") + elseif shiftHeld then + -- Show RA/MA ratios + raRatio:visible(true) + laRatio:visible(false) + maRatio:visible(true) + paRatio:visible(false) + + maRatio:settextf("%.1f:1", marvs / perfectTaps) -- marv:perf + raRatio:xy(paRatio:GetX() - maRatio:GetZoomedWidth() - 10, paRatio:GetY()) + maRatio:xy(paRatio:GetX(), paRatio:GetY()) + local ratioTextX = raRatio:GetX() - raRatio:GetZoomedWidth() - 10 + ratioText:xy(ratioTextX, paRatio:GetY()) - -- Align ratioText and maRatio to paRatio (self) - maRatioX = paRatio:GetX() - paRatio:GetZoomedWidth() - 10 - maRatio:xy(maRatioX, paRatio:GetY()) + ratioText:settextf("RA/MA ratio:") + else + -- Show MA/PA ratios + raRatio:visible(false) + laRatio:visible(false) + maRatio:visible(true) + paRatio:visible(true) + + maRatio:settextf("%.1f:1", marvelousTaps / perfectTaps) -- marv:perf + local maRatioX = paRatio:GetX() - paRatio:GetZoomedWidth() - 10 + maRatio:xy(maRatioX, paRatio:GetY()) + local ratioTextX = maRatioX - maRatio:GetZoomedWidth() - 10 + ratioText:xy(ratioTextX, paRatio:GetY()) + + ratioText:settextf("%s:", translated_info["MAPARatio"]) + end - ratioTextX = maRatioX - maRatio:GetZoomedWidth() - 10 - ratioText:xy(ratioTextX, paRatio:GetY()) if score:GetChordCohesion() == true then maRatio:maxwidth(maRatio:GetZoomedWidth()/0.25) self:maxwidth(self:GetZoomedWidth()/0.25) ratioText:maxwidth(capWideScale(get43size(65), 85)/0.27) end end, + + ShiftPressedMessageCommand = function(self) + self:playcommand("Set") + end, + ShiftReleasedMessageCommand = function(self) + self:playcommand("Set") + end, + AltPressedMessageCommand = function(self) + self:playcommand("Set") + end, + AltReleasedMessageCommand = function(self) + self:playcommand("Set") + end, + CodeMessageCommand = function(self, params) if usingCustomWindows then return end if params.Name == "PrevJudge" or params.Name == "NextJudge" then - marvelousTaps = getRescoredJudge(dvt, judge, 1) - perfectTaps = getRescoredJudge(dvt, judge, 2) - greatTaps = getRescoredJudge(dvt, judge, 3) + marvelousTaps = getRescoredJudge(dvt, judge, 1) + perfectTaps = getRescoredJudge(dvt, judge, 2) + greatTaps = getRescoredJudge(dvt, judge, 3) self:playcommand("Set") end if params.Name == "ResetJudge" then