2021-08-07 20:35:00 +02:00
require ( ' common ' )
2021-12-23 03:52:12 +01:00
local Easing = require ( ' common.easing ' )
2021-12-02 03:41:12 +01:00
local Background = require ( ' components.background ' )
2022-03-30 17:40:39 +02:00
local Dim = require ( " common.dimensions " )
local Wallpaper = require ( " components.wallpaper " )
2022-03-04 04:06:19 +01:00
local common = require ( ' common.util ' )
local Sound = require ( " common.sound " )
local Numbers = require ( ' components.numbers ' )
2021-08-09 20:48:31 +02:00
2021-12-02 03:41:12 +01:00
local VolforceCalc = require ( ' components.volforceCalc ' )
2021-08-12 21:21:42 +02:00
2021-08-01 20:00:45 +02:00
local dataPanelImage = gfx.CreateSkinImage ( " song_select/data_bg_overlay.png " , 1 )
local dataGlowOverlayImage = gfx.CreateSkinImage ( " song_select/data_panel/data_glow_overlay.png " , 1 )
local gradeBgImage = gfx.CreateSkinImage ( " song_select/data_panel/grade_bg.png " , 1 )
local badgeBgImage = gfx.CreateSkinImage ( " song_select/data_panel/clear_badge_bg.png " , 1 )
local effectedBgImage = gfx.CreateSkinImage ( " song_select/data_panel/effected_bg.png " , 1 )
local illustratedBgImage = gfx.CreateSkinImage ( " song_select/data_panel/illust_bg.png " , 1 )
2021-07-30 16:37:01 +02:00
local songPlateBg = gfx.CreateSkinImage ( " song_select/plate/bg.png " , 1 )
local songPlateBottomBarOverlayImage = gfx.CreateSkinImage ( " song_select/plate/bottom_bar_overlay.png " , 1 )
2021-10-25 21:06:06 +02:00
local scoreBoardBarBgImage = gfx.CreateSkinImage ( " song_select/textboard.png " , 1 )
2021-10-24 21:51:41 +02:00
local crownImage = gfx.CreateSkinImage ( " song_select/crown.png " , 1 )
2021-08-16 15:58:28 +02:00
2021-08-16 16:29:21 +02:00
local laserAnimBaseImage = gfx.CreateSkinImage ( " song_select/laser_anim.png " , 1 )
2021-08-16 15:50:53 +02:00
local top50OverlayImage = gfx.CreateSkinImage ( " song_select/top50.png " , 1 )
2021-08-16 15:58:28 +02:00
local top50JacketOverlayImage = gfx.CreateSkinImage ( " song_select/top50_jacket.png " , 1 )
2021-07-30 16:37:01 +02:00
2021-07-31 22:53:05 +02:00
local diffCursorImage = gfx.CreateSkinImage ( " song_select/level_cursor.png " , 1 )
2021-07-30 18:27:43 +02:00
2022-03-16 05:51:53 +01:00
local scrollBarBackgroundImage = gfx.CreateSkinImage ( " song_select/scrollbar/bg.png " , 1 )
local scrollBarFillImage = gfx.CreateSkinImage ( " song_select/scrollbar/fill.png " , 1 )
2021-08-13 17:35:26 +02:00
local filterInfoBgImage = gfx.CreateSkinImage ( " song_select/filter_info_bg.png " , 1 )
2021-08-14 17:49:12 +02:00
local sortInfoBgImage = gfx.CreateSkinImage ( " song_select/sort_info_bg.png " , 1 )
2021-08-13 17:35:26 +02:00
2021-08-05 22:01:17 +02:00
local searchBgImage = gfx.CreateSkinImage ( " song_select/search_bg.png " , 1 )
2022-03-11 00:43:19 +01:00
local searchActiveImage = gfx.CreateSkinImage ( " song_select/search_active.png " , 1 )
2022-03-09 09:24:21 +01:00
local searchInfoPanelImage = gfx.CreateSkinImage ( " song_select/search_info_panel.png " , 1 )
2021-08-05 22:01:17 +02:00
2021-07-30 18:40:49 +02:00
local defaultJacketImage = gfx.CreateSkinImage ( " song_select/loading.png " , 0 )
2022-03-11 02:02:48 +01:00
2021-07-30 16:37:01 +02:00
local difficultyLabelImages = {
gfx.CreateSkinImage ( " song_select/plate/difficulty_labels/novice.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/plate/difficulty_labels/advanced.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/plate/difficulty_labels/exhaust.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/plate/difficulty_labels/maximum.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/plate/difficulty_labels/infinite.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/plate/difficulty_labels/gravity.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/plate/difficulty_labels/heavenly.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/plate/difficulty_labels/vivid.png " , 1 ) ,
2021-07-25 20:10:06 +02:00
}
2021-07-30 18:27:43 +02:00
local badgeImages = {
gfx.CreateSkinImage ( " song_select/medal/nomedal.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/medal/played.png " , 1 ) ,
2021-07-30 18:40:49 +02:00
gfx.CreateSkinImage ( " song_select/medal/clear.png " , 1 ) ,
2021-07-30 18:27:43 +02:00
gfx.CreateSkinImage ( " song_select/medal/hard.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/medal/uc.png " , 1 ) ,
gfx.CreateSkinImage ( " song_select/medal/puc.png " , 1 ) ,
}
2021-11-20 19:27:28 +01:00
local cursorImages = {
gfx.CreateSkinImage ( " song_select/cursor.png " , 1 ) , -- Effective rate or fallback
gfx.CreateSkinImage ( " song_select/cursor_exc.png " , 1 ) , -- Excessive rate
gfx.CreateSkinImage ( " song_select/cursor_perm.png " , 1 ) , -- Premissive rate
gfx.CreateSkinImage ( " song_select/cursor_blast.png " , 1 ) , -- Blastive rate
}
2021-07-31 18:43:17 +02:00
local gradeCutoffs = {
D = 0000000 ,
C = 7000000 ,
B = 8000000 ,
A = 8700000 ,
A_P = 9000000 ,
AA = 9300000 ,
AA_P = 9500000 ,
AAA = 9700000 ,
AAA_P = 9800000 ,
S = 9900000 ,
}
local gradeImages = {
S = gfx.CreateSkinImage ( " common/grades/S.png " , 0 ) ,
AAA_P = gfx.CreateSkinImage ( " common/grades/AAA+.png " , 0 ) ,
AAA = gfx.CreateSkinImage ( " common/grades/AAA.png " , 0 ) ,
AA_P = gfx.CreateSkinImage ( " common/grades/AA+.png " , 0 ) ,
AA = gfx.CreateSkinImage ( " common/grades/AA.png " , 0 ) ,
A_P = gfx.CreateSkinImage ( " common/grades/A+.png " , 0 ) ,
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 ) ,
none = gfx.CreateSkinImage ( " common/grades/none.png " , 0 ) ,
}
2021-07-31 22:53:05 +02:00
local difficultyLabelUnderImages = {
gfx.CreateSkinImage ( " songtransition/difficulty_labels/nov.png " , 0 ) ,
gfx.CreateSkinImage ( " songtransition/difficulty_labels/adv.png " , 0 ) ,
gfx.CreateSkinImage ( " songtransition/difficulty_labels/exh.png " , 0 ) ,
gfx.CreateSkinImage ( " songtransition/difficulty_labels/mxm.png " , 0 ) ,
gfx.CreateSkinImage ( " songtransition/difficulty_labels/inf.png " , 0 ) ,
gfx.CreateSkinImage ( " songtransition/difficulty_labels/grv.png " , 0 ) ,
gfx.CreateSkinImage ( " songtransition/difficulty_labels/hvn.png " , 0 ) ,
gfx.CreateSkinImage ( " songtransition/difficulty_labels/vvd.png " , 0 ) ,
}
2022-03-30 17:40:39 +02:00
game.LoadSkinSample ( ' song_wheel/cursor_change.wav ' )
game.LoadSkinSample ( ' song_wheel/diff_change.wav ' )
2021-07-30 22:06:08 +02:00
2021-12-02 03:41:12 +01:00
local scoreNumbers = Numbers.load_number_image ( " score_num " )
local difficultyNumbers = Numbers.load_number_image ( " diff_num " )
2021-07-25 20:10:06 +02:00
2021-12-14 19:08:46 +01:00
local LEADERBOARD_PLACE_NAMES = {
' 1st ' ,
' 2nd ' ,
' 3rd ' ,
' 4th ' ,
}
2022-03-30 17:40:39 +02:00
local songPlateHeight = 172
2021-07-30 21:34:36 +02:00
2022-03-30 17:40:39 +02:00
local selectedIndex = 1
local selectedDifficulty = 1
2021-07-25 20:10:06 +02:00
2021-07-30 16:37:01 +02:00
local jacketCache = { }
2021-07-25 20:10:06 +02:00
2021-08-16 15:50:53 +02:00
local top50diffs = { }
2022-03-30 17:40:39 +02:00
local irRequestStatus = 1 -- 0=unused, 1=not requested, 2=loading, others are status codes
2021-12-14 20:02:25 +01:00
local irRequestTimeout = 2
2021-12-14 19:08:46 +01:00
local irLeaderboard = { }
2021-12-16 18:01:33 +01:00
local irLeaderboardsCache = { }
2021-12-14 19:08:46 +01:00
2022-03-30 17:40:39 +02:00
local transitionScrollScale = 0
local transitionScrollOffsetY = 0
local scrollingUp = false
2021-07-30 21:34:36 +02:00
2022-03-30 17:40:39 +02:00
local transitionAfterscrollScale = 0
local transitionAfterscrollDataOverlayAlpha = 0
local transitionAfterscrollGradeAlpha = 0
local transitionAfterscrollBadgeAlpha = 0
local transitionAfterscrollTextSongTitle = 0
local transitionAfterscrollTextSongArtist = 0
local transitionAfterscrollDifficultiesAlpha = 0
2021-07-31 22:14:34 +02:00
2022-03-30 17:40:39 +02:00
local transitionJacketBgScrollScale = 0
local transitionJacketBgScrollAlpha = 0
local transitionJacketBgScrollPosX = 0
2021-08-26 19:50:33 +02:00
2022-03-09 09:24:21 +01:00
--search
2022-03-30 17:40:39 +02:00
local searchPreviousActiveState = false
local searchInfoPreviousActiveState = false
local transitionSearchEnterScale = 0
local transitionSearchInfoEnterScale = 0
local transitionSearchBackgroundAlpha = 0
local transitionSearchbarOffsetY = 0
local transitionSearchInfoOffsetY = 0
2022-03-09 09:24:21 +01:00
2022-03-30 17:40:39 +02:00
local transitionLaserScale = 0
local transitionLaserY = 0
2021-08-16 16:29:21 +02:00
2021-08-26 15:31:28 +02:00
-- Flash transition (animation)
-- Used for flashing the badges
-- 0 = minimum brightness; 0.5 = maximum brightness; 1 = minimum brightness again
2022-03-30 17:40:39 +02:00
local transitionFlashScale = 0
local transitionFlashAlpha = 1
2021-08-26 15:31:28 +02:00
2022-03-30 17:40:39 +02:00
local isFilterWheelActive = false
local transitionLeaveScale = 0
local transitionLeaveReappearTimer = 0
local TRANSITION_LEAVE_DURATION = 0.1
2021-08-09 20:48:31 +02:00
2021-11-22 20:23:34 +01:00
-- Window variables
local resX , resY
-- Aspect Ratios
local landscapeWidescreenRatio = 16 / 9
local landscapeStandardRatio = 4 / 3
local portraitWidescreenRatio = 9 / 16
-- Portrait sizes
local fullX , fullY
local desw = 1080
local desh = 1920
local resolutionChange = function ( x , y )
resX = x
resY = y
fullX = portraitWidescreenRatio * y
fullY = y
2022-03-30 17:40:39 +02:00
game.Log ( ' resX: ' .. resX .. ' // resY: ' .. resY .. ' // fullX: ' .. fullX .. ' // fullY: ' .. fullY , game.LOGGER_ERROR )
2021-07-25 20:10:06 +02:00
end
2021-07-30 20:18:03 +02:00
function getCorrectedIndex ( from , offset )
2022-03-30 17:40:39 +02:00
total = # songwheel.songs
2021-07-30 20:18:03 +02:00
2021-08-12 22:34:38 +02:00
if ( math.abs ( offset ) > total ) then
if ( offset < 0 ) then
2022-03-30 17:40:39 +02:00
offset = offset + total * math.floor ( math.abs ( offset ) / total )
2021-08-12 22:34:38 +02:00
else
2022-03-30 17:40:39 +02:00
offset = offset - total * math.floor ( math.abs ( offset ) / total )
2021-08-12 22:34:38 +02:00
end
end
2022-03-30 17:40:39 +02:00
index = from + offset
2021-07-30 20:18:03 +02:00
if index < 1 then
index = total + ( from + offset ) -- this only happens if the offset is negative
2022-03-30 17:40:39 +02:00
end
2021-07-30 20:18:03 +02:00
if index > total then
2022-03-30 17:40:39 +02:00
indexesUntilEnd = total - from
2021-07-30 20:18:03 +02:00
index = offset - indexesUntilEnd -- this only happens if the offset is positive
2022-03-30 17:40:39 +02:00
end
2021-07-30 20:18:03 +02:00
2022-03-30 17:40:39 +02:00
return index
end
2021-07-30 20:18:03 +02:00
2021-07-30 16:37:01 +02:00
function getJacketImage ( song )
2021-07-31 19:36:47 +02:00
if not jacketCache [ song.id ] or jacketCache [ song.id ] == defaultJacketImage then
2021-08-13 22:36:21 +02:00
jacketCache [ song.id ] = gfx.LoadImageJob ( song.difficulties [
math.min ( selectedDifficulty , # song.difficulties )
2022-03-30 17:40:39 +02:00
] . jacketPath , defaultJacketImage , 500 , 500 )
2021-07-25 20:10:06 +02:00
end
2022-03-30 17:40:39 +02:00
return jacketCache [ song.id ]
2021-07-25 20:10:06 +02:00
end
2021-07-31 18:43:17 +02:00
function getGradeImageForScore ( score )
2022-03-30 17:40:39 +02:00
local gradeImage = gradeImages.none
local bestGradeCutoff = 0
2021-07-31 18:43:17 +02:00
for gradeName , scoreCutoff in pairs ( gradeCutoffs ) do
if scoreCutoff <= score then
if scoreCutoff > bestGradeCutoff then
2022-03-30 17:40:39 +02:00
gradeImage = gradeImages [ gradeName ]
bestGradeCutoff = scoreCutoff
2021-07-31 18:43:17 +02:00
end
end
end
2022-03-30 17:40:39 +02:00
return gradeImage
2021-07-31 18:43:17 +02:00
end
2021-08-16 16:29:21 +02:00
function drawLaserAnim ( )
2022-03-30 17:40:39 +02:00
gfx.Save ( )
2021-08-16 16:29:21 +02:00
gfx.BeginPath ( )
2021-11-22 22:25:38 +01:00
2022-03-30 17:40:39 +02:00
gfx.Scissor ( 0 , transitionLaserY , desw , 100 )
2021-11-22 22:25:38 +01:00
2021-08-16 16:29:21 +02:00
gfx.ImageRect ( 0 , 0 , desw , desh , laserAnimBaseImage , 1 , 0 )
2021-11-22 22:25:38 +01:00
2022-03-30 17:40:39 +02:00
gfx.Restore ( )
2021-08-16 16:29:21 +02:00
end
2021-08-02 19:55:17 +02:00
function drawBackground ( deltaTime )
2021-08-21 13:52:40 +02:00
Background.draw ( deltaTime )
2021-11-20 19:12:12 +01:00
2022-03-30 17:40:39 +02:00
local song = songwheel.songs [ selectedIndex ]
local diff = song and song.difficulties [ selectedDifficulty ] or false
2021-08-06 20:04:34 +02:00
2021-11-20 19:34:15 +01:00
if ( not isFilterWheelActive and transitionLeaveReappearTimer == 0 ) then
2021-11-20 19:12:12 +01:00
-- If the score for song exists
if song and diff then
2022-03-30 17:40:39 +02:00
local jacketImage = getJacketImage ( song )
2021-11-20 19:12:12 +01:00
gfx.BeginPath ( )
gfx.ImageRect ( transitionJacketBgScrollPosX , 0 , 900 , 900 , jacketImage or defaultJacketImage , transitionJacketBgScrollAlpha , 0 )
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.FillColor ( 0 , 0 , 0 , math.floor ( transitionJacketBgScrollAlpha * 64 ) )
gfx.Rect ( 0 , 0 , 900 , 900 )
gfx.Fill ( )
gfx.ClosePath ( )
2021-11-20 19:12:12 +01:00
end
2021-08-01 20:00:45 +02:00
end
2021-08-11 20:00:35 +02:00
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
2021-08-01 20:00:45 +02:00
gfx.ImageRect ( 0 , 0 , desw , desh , dataPanelImage , 1 , 0 )
2021-08-16 16:29:21 +02:00
drawLaserAnim ( )
2021-08-11 20:00:35 +02:00
2021-11-20 19:34:15 +01:00
if song and diff and ( not isFilterWheelActive and transitionLeaveReappearTimer == 0 ) then
2021-08-01 20:00:45 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( 0 , 0 , desw , desh , dataGlowOverlayImage , transitionAfterscrollDataOverlayAlpha , 0 )
gfx.BeginPath ( )
gfx.ImageRect ( 341 , 754 , 85 , 85 , gradeBgImage , transitionAfterscrollDataOverlayAlpha , 0 )
gfx.BeginPath ( )
gfx.ImageRect ( 391 , 687 , 180 * 0.85 , 226 * 0.85 , badgeBgImage , transitionAfterscrollDataOverlayAlpha , 0 )
gfx.BeginPath ( )
gfx.ImageRect ( 95 , 1165 , 433 , 30 , effectedBgImage , transitionAfterscrollDataOverlayAlpha , 0 )
gfx.BeginPath ( )
gfx.ImageRect ( 95 , 1195 , 433 , 30 , illustratedBgImage , transitionAfterscrollDataOverlayAlpha , 0 )
2021-07-31 20:36:05 +02:00
end
2021-08-02 19:55:17 +02:00
2021-07-25 20:10:06 +02:00
end
2021-07-30 16:37:01 +02:00
function drawSong ( song , y )
2022-03-30 17:40:39 +02:00
if ( not song ) then return end
2021-07-31 20:36:05 +02:00
2021-07-30 16:37:01 +02:00
local songX = desw / 2 + 28
2021-08-12 21:47:16 +02:00
local selectedSongDifficulty = song.difficulties [ math.min ( selectedDifficulty , # song.difficulties ) ] -- Limit selecting difficulty that is above the number that the song has
2021-07-31 18:43:17 +02:00
if not selectedSongDifficulty then
2022-03-30 17:40:39 +02:00
return
2021-07-31 18:43:17 +02:00
end
2022-03-30 17:40:39 +02:00
local bestScore
2021-07-31 18:43:17 +02:00
if selectedSongDifficulty.scores then
2022-03-30 17:40:39 +02:00
bestScore = selectedSongDifficulty.scores [ 1 ]
2021-07-31 18:43:17 +02:00
end
2021-07-25 20:10:06 +02:00
2021-07-30 16:37:01 +02:00
-- Draw the bg for the song plate
gfx.BeginPath ( )
2021-07-30 16:42:01 +02:00
gfx.ImageRect ( songX , y , 515 , 172 , songPlateBg , 1 , 0 )
2021-07-30 16:37:01 +02:00
-- Draw jacket
2022-03-30 17:40:39 +02:00
local jacketImage = getJacketImage ( song )
2021-07-30 16:37:01 +02:00
gfx.BeginPath ( )
2021-07-30 18:40:49 +02:00
gfx.ImageRect ( songX + 4 , y + 4 , 163 , 163 , jacketImage or defaultJacketImage , 1 , 0 )
2021-07-25 20:10:06 +02:00
2021-07-30 16:37:01 +02:00
-- Draw the overlay for the song plate (that bottom black bar)
gfx.BeginPath ( )
2021-07-30 16:42:01 +02:00
gfx.ImageRect ( songX , y , 515 , 172 , songPlateBottomBarOverlayImage , 1 , 0 )
2021-07-30 16:37:01 +02:00
-- Draw the difficulty notch background
2021-07-25 20:10:06 +02:00
gfx.BeginPath ( )
2021-08-07 20:35:00 +02:00
local diffIndex = GetDisplayDifficulty ( selectedSongDifficulty.jacketPath , selectedSongDifficulty.difficulty )
gfx.ImageRect ( songX , y + 95 , 83 , 74 , difficultyLabelImages [ diffIndex ] , 1 , 0 )
2021-07-25 20:10:06 +02:00
2021-07-30 16:37:01 +02:00
-- Draw the difficulty level number
gfx.BeginPath ( )
2021-12-02 03:41:12 +01:00
Numbers.draw_number ( songX + 30 , y + 125 , 1.0 , selectedSongDifficulty.level , 2 , difficultyNumbers , false , 0.65 , 1 )
2021-07-30 18:27:43 +02:00
2021-07-30 22:10:04 +02:00
-- Draw song title
gfx.FontSize ( 24 )
gfx.TextAlign ( gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE )
2022-03-30 17:40:39 +02:00
gfx.Text ( song.title , songX + 90 , y + 155 )
2021-07-30 22:10:04 +02:00
2021-07-30 18:27:43 +02:00
-- Draw score badge
2022-03-30 17:40:39 +02:00
local badgeImage = badgeImages [ 1 ]
2021-08-12 18:08:27 +02:00
if selectedSongDifficulty.topBadge then
2022-03-30 17:40:39 +02:00
badgeImage = badgeImages [ selectedSongDifficulty.topBadge + 1 ]
2021-07-30 18:27:43 +02:00
end
2021-08-26 15:31:28 +02:00
2022-03-30 17:40:39 +02:00
local badgeAlpha = 1
2021-08-26 15:31:28 +02:00
if ( selectedSongDifficulty.topBadge >= 3 ) then
2022-03-30 17:40:39 +02:00
badgeAlpha = transitionFlashAlpha -- If hard clear or above, flash the badge
2021-08-26 15:31:28 +02:00
end
2021-07-30 18:27:43 +02:00
gfx.BeginPath ( )
2021-08-26 15:31:28 +02:00
gfx.ImageRect ( songX + 282 , y + 44 , 79 , 69 , badgeImage , badgeAlpha , 0 )
2021-07-31 18:43:17 +02:00
-- Draw grade
2022-03-30 17:40:39 +02:00
local gradeImage = gradeImages.none
local gradeAlpha = 1
2021-08-26 15:31:28 +02:00
2021-07-31 18:43:17 +02:00
if bestScore then
gradeImage = getGradeImageForScore ( bestScore.score )
2021-08-26 15:31:28 +02:00
if ( bestScore.score >= gradeCutoffs.S ) then
2022-03-30 17:40:39 +02:00
gradeAlpha = transitionFlashAlpha -- If S, flash the badge
2021-08-26 15:31:28 +02:00
end
2021-07-31 18:43:17 +02:00
end
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( songX + 391 , y + 47 , 60 , 60 , gradeImage , gradeAlpha , 0 )
2021-07-31 18:43:17 +02:00
2021-08-16 15:50:53 +02:00
-- Draw top 50 label if applicable
if ( top50diffs [ selectedSongDifficulty.id ] ) then
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( songX + 82 , y + 109 , 506 * 0.85 , 26 * 0.85 , top50OverlayImage , 1 , 0 )
2021-08-16 15:50:53 +02:00
end
2021-07-25 20:10:06 +02:00
end
2021-07-30 16:37:01 +02:00
function drawSongList ( )
2022-03-30 17:40:39 +02:00
gfx.GlobalAlpha ( 1 - transitionLeaveScale )
2021-11-20 19:12:12 +01:00
2022-03-30 17:40:39 +02:00
local numOfSongsAround = 7 -- How many songs should be up and how many should be down of the selected one
2021-07-30 21:34:36 +02:00
2022-03-30 17:40:39 +02:00
local yOffset = transitionScrollOffsetY
2021-07-30 20:07:04 +02:00
2022-03-30 17:40:39 +02:00
local i = 1
2021-07-30 20:07:04 +02:00
while ( i <= numOfSongsAround ) do
2021-07-30 20:18:03 +02:00
local songIndex = getCorrectedIndex ( selectedIndex , - i )
2021-08-12 16:55:10 +02:00
drawSong ( songwheel.songs [ songIndex ] , desh / 2 - songPlateHeight / 2 - songPlateHeight * i + yOffset )
2022-03-30 17:40:39 +02:00
i = i + 1
end
2021-07-30 20:07:04 +02:00
-- Draw the selected song
2021-08-12 16:55:10 +02:00
drawSong ( songwheel.songs [ selectedIndex ] , desh / 2 - songPlateHeight / 2 + yOffset )
2021-07-30 20:07:04 +02:00
2022-03-30 17:40:39 +02:00
i = 1
2021-07-30 20:07:04 +02:00
while ( i <= numOfSongsAround ) do
2021-07-30 20:18:03 +02:00
local songIndex = getCorrectedIndex ( selectedIndex , i )
2021-08-12 16:55:10 +02:00
drawSong ( songwheel.songs [ songIndex ] , desh / 2 - songPlateHeight / 2 + songPlateHeight * i + yOffset )
2022-03-30 17:40:39 +02:00
i = i + 1
end
2021-11-20 19:12:12 +01:00
2022-03-30 17:40:39 +02:00
gfx.GlobalAlpha ( 1 )
2021-07-25 20:10:06 +02:00
end
2021-07-31 20:36:05 +02:00
function drawData ( ) -- Draws the song data on the left panel
2021-11-20 19:12:12 +01:00
2022-03-30 17:40:39 +02:00
if isFilterWheelActive or transitionLeaveReappearTimer ~= 0 then return false end
2021-11-20 19:12:12 +01:00
2022-03-30 17:40:39 +02:00
local song = songwheel.songs [ selectedIndex ]
local diff = song and song.difficulties [ selectedDifficulty ] or false
local bestScore = diff and diff.scores [ 1 ]
2021-08-12 11:52:37 +02:00
if not song then return false end
2021-07-31 20:36:05 +02:00
2022-03-30 17:40:39 +02:00
local jacketImage = getJacketImage ( song )
2021-07-31 20:36:05 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( 96 , 324 , 348 , 348 , jacketImage or defaultJacketImage , 1 , 0 )
2021-08-16 15:58:28 +02:00
if ( top50diffs [ diff.id ] ) then
gfx.BeginPath ( )
gfx.ImageRect ( 96 , 529 , 410 * 0.85 , 168 * 0.85 , top50JacketOverlayImage , 1 , 0 )
end
2021-07-31 20:36:05 +02:00
2021-07-31 22:14:34 +02:00
gfx.Save ( )
2021-08-26 15:39:16 +02:00
-- Draw best score
gfx.BeginPath ( )
2022-03-30 17:40:39 +02:00
local scoreNumber = 0
2021-07-31 20:36:05 +02:00
if bestScore then
2021-08-26 15:42:50 +02:00
scoreNumber = bestScore.score
2021-08-26 15:39:16 +02:00
end
2021-07-31 20:36:05 +02:00
2021-12-02 03:41:12 +01:00
Numbers.draw_number ( 100 , 793 , 1.0 , math.floor ( scoreNumber / 10000 ) , 4 , scoreNumbers , true , 0.3 , 1.12 )
Numbers.draw_number ( 253 , 798 , 1.0 , scoreNumber , 4 , scoreNumbers , true , 0.22 , 1.12 )
2021-08-26 15:42:50 +02:00
2021-08-26 15:39:16 +02:00
-- Draw grade
2022-03-30 17:40:39 +02:00
local gradeImage = gradeImages.none
local gradeAlpha = transitionAfterscrollGradeAlpha
2021-08-26 15:39:16 +02:00
if bestScore then
gradeImage = getGradeImageForScore ( bestScore.score )
2021-08-26 15:36:47 +02:00
2021-08-26 15:39:16 +02:00
if ( transitionAfterscrollGradeAlpha == 1 and bestScore.score >= gradeCutoffs.S ) then
2022-03-30 17:40:39 +02:00
gradeAlpha = transitionFlashAlpha -- If S, flash the badge
2021-07-31 20:36:05 +02:00
end
2021-08-26 15:39:16 +02:00
end
2021-07-31 20:36:05 +02:00
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( 360 , 773 , 45 , 45 , gradeImage , gradeAlpha , 0 )
2021-08-26 15:36:47 +02:00
2021-08-26 15:39:16 +02:00
-- Draw badge
2022-03-30 17:40:39 +02:00
badgeImage = badgeImages [ diff.topBadge + 1 ]
2021-08-26 15:36:47 +02:00
2022-03-30 17:40:39 +02:00
local badgeAlpha = transitionAfterscrollBadgeAlpha
2021-08-26 15:39:16 +02:00
if ( transitionAfterscrollBadgeAlpha == 1 and diff.topBadge >= 3 ) then
2022-03-30 17:40:39 +02:00
badgeAlpha = transitionFlashAlpha -- If hard clear or above, flash the badge, but only after the initial transition
2021-07-31 20:36:05 +02:00
end
2021-08-26 15:39:16 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( 425 , 724 , 93 / 1.1 , 81 / 1.1 , badgeImage , badgeAlpha , 0 )
2021-07-31 22:14:34 +02:00
gfx.Restore ( )
2021-07-31 20:36:05 +02:00
-- Draw BPM
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
2021-07-31 20:36:05 +02:00
gfx.FontSize ( 24 )
gfx.TextAlign ( gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE )
gfx.Save ( )
gfx.LoadSkinFont ( ' Digital-Serial-Bold.ttf ' )
2021-08-01 18:08:52 +02:00
gfx.GlobalAlpha ( transitionAfterscrollDataOverlayAlpha ) -- TODO: split this out
2022-03-30 17:40:39 +02:00
gfx.Text ( song.bpm , 85 , 920 )
2021-07-31 20:36:05 +02:00
gfx.Restore ( )
-- Draw song title
gfx.FontSize ( 28 )
2022-03-30 17:40:39 +02:00
gfx.GlobalAlpha ( transitionAfterscrollTextSongTitle )
gfx.Text ( song.title , 30 + ( 1 - transitionAfterscrollTextSongTitle ) * 20 , 955 )
2021-08-01 18:08:52 +02:00
2021-07-31 20:36:05 +02:00
-- Draw artist
2022-03-30 17:40:39 +02:00
gfx.GlobalAlpha ( transitionAfterscrollTextSongArtist )
gfx.Text ( song.artist , 30 + ( 1 - transitionAfterscrollTextSongArtist ) * 30 , 997 )
2021-08-01 18:08:52 +02:00
2022-03-30 17:40:39 +02:00
gfx.GlobalAlpha ( 1 )
2021-07-31 22:53:05 +02:00
-- Draw difficulties
local DIFF_X_START = 98.5
2022-03-30 17:40:39 +02:00
local DIFF_GAP = 114.8
gfx.GlobalAlpha ( transitionAfterscrollDifficultiesAlpha )
2021-08-12 15:53:29 +02:00
for i , diff in ipairs ( song.difficulties ) do
2021-07-31 22:53:05 +02:00
gfx.BeginPath ( )
2021-08-12 15:53:29 +02:00
local index = diff.difficulty + 1
if i == selectedDifficulty then
2021-07-31 22:53:05 +02:00
gfx.ImageRect ( DIFF_X_START + ( index - 1 ) * DIFF_GAP - ( 163 * 0.8 ) / 2 , 1028 , 163 * 0.8 , 163 * 0.8 , diffCursorImage , 1 , 0 )
end
2021-12-02 03:41:12 +01:00
Numbers.draw_number ( 85 + ( index - 1 ) * DIFF_GAP , 1085 , 1.0 , diff.level , 2 , difficultyNumbers , false , 0.8 , 1 )
2021-07-31 22:53:05 +02:00
2021-08-07 20:35:00 +02:00
local diffLabelImage = difficultyLabelUnderImages [
GetDisplayDifficulty ( diff.jacketPath , diff.difficulty )
2022-03-30 17:40:39 +02:00
]
2021-07-31 22:53:05 +02:00
local tw , th = gfx.ImageSize ( diffLabelImage )
tw = tw * 0.9
th = th * 0.9
gfx.BeginPath ( )
gfx.ImageRect ( DIFF_X_START + ( index - 1 ) * DIFF_GAP - tw / 2 , 1050 , tw , th , diffLabelImage , 1 , 0 )
end
2022-03-30 17:40:39 +02:00
gfx.GlobalAlpha ( 1 )
2021-10-25 21:06:06 +02:00
2021-08-01 20:07:48 +02:00
2021-10-25 21:06:06 +02:00
-- Scoreboard
2021-08-01 20:07:48 +02:00
2021-12-14 19:08:46 +01:00
drawLocalLeaderboard ( diff )
drawIrLeaderboard ( )
gfx.FontSize ( 22 )
2021-12-16 16:52:03 +01:00
gfx.TextAlign ( gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE )
2022-03-30 17:40:39 +02:00
gfx.GlobalAlpha ( transitionAfterscrollDataOverlayAlpha )
gfx.Text ( diff.effector , 270 , 1180 ) -- effected by
gfx.Text ( diff.illustrator , 270 , 1210 ) -- illustrated by
gfx.GlobalAlpha ( 1 )
2021-12-14 19:08:46 +01:00
end
function drawLocalLeaderboard ( diff )
2021-10-24 21:51:41 +02:00
gfx.LoadSkinFont ( ' Digital-Serial-Bold.ttf ' )
2021-12-14 19:08:46 +01:00
gfx.FontSize ( 26 )
2021-10-24 21:51:41 +02:00
2022-03-30 17:40:39 +02:00
local scoreBoardX = 75
local scoreBoardY = 1250
2021-08-01 20:07:48 +02:00
2022-03-30 17:40:39 +02:00
local sbBarWidth = 336 * 1.2
local sbBarHeight = 33
2021-10-24 21:51:41 +02:00
2022-03-30 17:40:39 +02:00
local sbBarContentLeftX = scoreBoardX + 80
local sbBarContentRightX = scoreBoardX + sbBarWidth / 2 + 30
2021-10-24 21:51:41 +02:00
2021-10-25 21:06:06 +02:00
-- Draw the header
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( scoreBoardX , scoreBoardY , sbBarWidth , sbBarHeight , scoreBoardBarBgImage , 1 , 0 )
2021-10-24 21:51:41 +02:00
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( 205 , 1252.5 , 800 * 0.045 , 600 * 0.045 , crownImage , 1 , 0 )
2021-10-24 21:51:41 +02:00
2021-10-25 21:06:06 +02:00
gfx.TextAlign ( gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE )
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.Text ( " LOCAL TOP " , sbBarContentRightX , scoreBoardY + sbBarHeight / 2 )
2021-10-24 21:51:41 +02:00
2021-10-25 21:06:06 +02:00
for i = 1 , 5 , 1 do
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( scoreBoardX , scoreBoardY + i * sbBarHeight , sbBarWidth , sbBarHeight , scoreBoardBarBgImage , 1 , 0 )
2021-10-25 21:06:06 +02:00
2021-12-14 19:08:46 +01:00
gfx.TextAlign ( gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE )
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.Text ( game.GetSkinSetting ( " username " ) , sbBarContentLeftX , scoreBoardY + sbBarHeight / 2 + i * sbBarHeight )
2021-10-25 21:06:06 +02:00
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.Text ( ( diff.scores [ i ] ) and diff.scores [ i ] . score or " - - - - - - - - " , sbBarContentRightX , scoreBoardY + sbBarHeight / 2 + i * sbBarHeight )
2021-10-25 21:06:06 +02:00
end
2021-12-14 19:08:46 +01:00
end
2021-10-24 21:51:41 +02:00
2021-12-14 19:08:46 +01:00
function drawIrLeaderboard ( )
2021-12-16 18:29:04 +01:00
if not IRData.Active then
2022-03-30 17:40:39 +02:00
return
2021-12-16 18:29:04 +01:00
end
2021-12-14 19:08:46 +01:00
gfx.LoadSkinFont ( ' Digital-Serial-Bold.ttf ' )
gfx.FontSize ( 26 )
2021-12-16 16:52:03 +01:00
2022-03-30 17:40:39 +02:00
local scoreBoardX = 75
local scoreBoardY = 1500
2021-12-16 16:52:03 +01:00
2022-03-30 17:40:39 +02:00
local sbBarWidth = 336 * 1.2
local sbBarHeight = 33
2021-12-16 16:52:03 +01:00
2022-03-30 17:40:39 +02:00
local sbBarContentLeftX = scoreBoardX + 80
local sbBarContentRightX = scoreBoardX + sbBarWidth / 2 + 30
2021-12-14 19:08:46 +01:00
-- Draw the header
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( scoreBoardX , scoreBoardY , sbBarWidth , sbBarHeight , scoreBoardBarBgImage , 1 , 0 )
2021-12-16 16:52:03 +01:00
gfx.TextAlign ( gfx.TEXT_ALIGN_CENTER + gfx.TEXT_ALIGN_MIDDLE )
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
2021-12-16 16:52:03 +01:00
2021-12-16 17:31:38 +01:00
if irRequestStatus == 1 or irRequestStatus == 2 then
2022-03-30 17:40:39 +02:00
gfx.Text ( " Loading ranking... " , scoreBoardX + ( sbBarWidth / 2 ) , scoreBoardY + sbBarHeight / 2 )
return
2021-12-16 16:52:03 +01:00
end
if irRequestStatus == IRData.States . ChartRefused then
2022-03-30 17:40:39 +02:00
gfx.Text ( " This chart is blacklisted " , scoreBoardX + ( sbBarWidth / 2 ) , scoreBoardY + sbBarHeight / 2 )
return
2021-12-16 16:52:03 +01:00
end
if irRequestStatus == IRData.States . NotFound then
2022-03-30 17:40:39 +02:00
gfx.Text ( " This chart is not tracked " , scoreBoardX + ( sbBarWidth / 2 ) , scoreBoardY + sbBarHeight / 2 )
return
2021-12-16 16:52:03 +01:00
end
if # irLeaderboard == 0 then
2022-03-30 17:40:39 +02:00
gfx.Text ( " This chart has no scores " , scoreBoardX + ( sbBarWidth / 2 ) , scoreBoardY + sbBarHeight / 2 )
return
2021-12-16 16:52:03 +01:00
end
2021-12-14 19:08:46 +01:00
gfx.TextAlign ( gfx.TEXT_ALIGN_CENTER + gfx.TEXT_ALIGN_MIDDLE )
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.Text ( " IR TOP " , scoreBoardX + ( sbBarWidth / 2 ) , scoreBoardY + sbBarHeight / 2 )
2021-12-14 19:08:46 +01:00
for i = 1 , 4 , 1 do
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( scoreBoardX , scoreBoardY + i * sbBarHeight , sbBarWidth , sbBarHeight , scoreBoardBarBgImage , 1 , 0 )
2021-12-14 20:23:45 +01:00
end
2021-12-14 19:08:46 +01:00
2021-12-14 20:23:45 +01:00
-- Becuase the scores are in "random order", we have to do this
2021-12-14 22:22:38 +01:00
for index , irScore in ipairs ( irLeaderboard ) do
2022-03-30 17:40:39 +02:00
-- local irScore = irLeaderboard[i]
2021-12-14 20:23:45 +01:00
2021-12-14 19:08:46 +01:00
if irScore then
2022-03-30 17:40:39 +02:00
local rank = index
2021-12-14 19:08:46 +01:00
gfx.TextAlign ( gfx.TEXT_ALIGN_CENTER + gfx.TEXT_ALIGN_MIDDLE )
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.Text ( LEADERBOARD_PLACE_NAMES [ rank ] , sbBarContentLeftX - 40 , scoreBoardY + sbBarHeight / 2 + rank * sbBarHeight )
2021-12-14 19:08:46 +01:00
gfx.TextAlign ( gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE )
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.Text ( string.upper ( irScore.username ) , sbBarContentLeftX , scoreBoardY + sbBarHeight / 2 + rank * sbBarHeight )
2021-12-14 19:08:46 +01:00
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.Text ( string.format ( " %d " , irScore.score ) , sbBarContentRightX , scoreBoardY + sbBarHeight / 2 + rank * sbBarHeight )
2021-10-24 21:51:41 +02:00
2022-03-30 17:40:39 +02:00
local badgeImage = badgeImages [ irScore.lamp + 1 ]
2021-12-14 19:08:46 +01:00
gfx.BeginPath ( )
2021-12-14 20:23:45 +01:00
gfx.ImageRect ( scoreBoardX + sbBarWidth - 50 , scoreBoardY + sbBarHeight / 2 + rank * sbBarHeight - 12.5 , 31.6 , 27.6 , badgeImage , 1 , 0 )
2021-12-14 19:08:46 +01:00
end
end
2021-07-31 20:36:05 +02:00
end
2021-08-13 17:35:26 +02:00
function drawFilterInfo ( deltatime )
2021-11-20 19:27:28 +01:00
gfx.LoadSkinFont ( ' NotoSans-Regular.ttf ' )
2021-11-20 19:34:15 +01:00
2021-12-18 21:39:47 +01:00
if ( songwheel.searchInputActive ) then
2022-03-30 17:40:39 +02:00
--return
2021-12-18 21:39:47 +01:00
end
2021-08-13 17:35:26 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( 5 , 95 , 417 * 0.85 , 163 * 0.85 , filterInfoBgImage , 1 , 0 )
local folderLabel = game.GetSkinSetting ( ' _songWheelActiveFolderLabel ' )
local subFolderLabel = game.GetSkinSetting ( ' _songWheelActiveSubFolderLabel ' )
2021-08-14 17:49:12 +02:00
local sortOptionLabel = game.GetSkinSetting ( ' _songWheelActiveSortOptionLabel ' )
2021-08-13 17:35:26 +02:00
gfx.FontSize ( 24 )
gfx.TextAlign ( gfx.TEXT_ALIGN_CENTER + gfx.TEXT_ALIGN_MIDDLE )
2021-08-14 17:49:12 +02:00
2021-08-13 17:35:26 +02:00
gfx.BeginPath ( )
2022-03-30 17:40:39 +02:00
gfx.Text ( folderLabel or ' ' , 167 , 131 )
2021-08-14 17:49:12 +02:00
2021-08-13 17:35:26 +02:00
gfx.BeginPath ( )
2022-03-30 17:40:39 +02:00
gfx.Text ( subFolderLabel or ' ' , 195 , 166 )
2021-08-14 17:49:12 +02:00
gfx.BeginPath ( )
gfx.ImageRect ( desw - 310 - 5 , 108 , 310 , 75 , sortInfoBgImage , 1 , 0 )
gfx.BeginPath ( )
2022-03-30 17:40:39 +02:00
gfx.Text ( sortOptionLabel or ' ' , desw - 150 , 130 )
2021-08-13 17:35:26 +02:00
end
2021-11-20 19:27:28 +01:00
function drawCursor ( )
if isFilterWheelActive or transitionLeaveScale ~= 0 then return false end
gfx.BeginPath ( )
local cursorImageIndex = game.GetSkinSetting ( ' _gaugeType ' )
2022-03-30 17:40:39 +02:00
local cursorImage = cursorImages [ cursorImageIndex or 1 ]
2021-11-20 19:27:28 +01:00
gfx.ImageRect ( desw / 2 - 14 , desh / 2 - 213 / 2 , 555 , 213 , cursorImage , 1 , 0 )
end
2021-08-05 22:01:17 +02:00
function drawSearch ( )
2022-03-09 09:24:21 +01:00
if ( not songwheel.searchInputActive and searchPreviousActiveState ) then
2022-03-30 17:40:39 +02:00
searchPreviousActiveState = false
game.PlaySample ( ' sort_wheel/enter.wav ' )
2022-03-09 09:24:21 +01:00
elseif ( songwheel.searchInputActive and not searchPreviousActiveState ) then
2022-03-30 17:40:39 +02:00
searchPreviousActiveState = true
game.PlaySample ( ' sort_wheel/leave.wav ' )
2022-03-09 09:24:21 +01:00
end
2022-03-11 00:43:19 +01:00
if ( songwheel.searchText ~= ' ' and searchInfoPreviousActiveState == true ) then
2022-03-30 17:40:39 +02:00
searchInfoPreviousActiveState = false
2022-03-11 00:43:19 +01:00
elseif ( songwheel.searchText == ' ' and searchInfoPreviousActiveState == false ) then
2022-03-30 17:40:39 +02:00
searchInfoPreviousActiveState = true
2022-03-11 00:43:19 +01:00
end
2022-03-09 09:24:21 +01:00
if ( transitionSearchEnterScale == 0 ) then
2022-03-30 17:40:39 +02:00
return
2021-08-05 22:01:17 +02:00
end
2022-03-09 09:24:21 +01:00
-- Draw dark overlay over Songwheel
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
gfx.FillColor ( 0 , 0 , 0 , math.floor ( transitionSearchBackgroundAlpha * 192 ) )
gfx.Rect ( 0 , 0 , 1080 , 1920 )
gfx.Fill ( )
2021-08-05 22:01:17 +02:00
2022-03-09 09:24:21 +01:00
-- Draw search info panel
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
local infoResize = 0.855
2022-03-11 02:02:48 +01:00
local sw , sh = gfx.ImageSize ( searchInfoPanelImage )
2022-03-30 17:40:39 +02:00
sw = sw * infoResize
sh = sh * infoResize
local infoXPos = 0
local infoYStartPos = desh - sh - 772 + 242
local infoYPos = infoYStartPos + transitionSearchInfoOffsetY
2022-03-11 02:02:48 +01:00
if ( game.GetSkinSetting ( ' gameplay_showSearchControls ' ) ) then
gfx.ImageRect ( infoXPos , infoYPos , sw , sh , searchInfoPanelImage , transitionSearchBackgroundInfoAlpha , 0 )
end
2022-03-11 00:43:19 +01:00
-- Draw Search is Active text
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
local activeResize = 0.855
2022-03-11 00:43:19 +01:00
local activew , activeh = gfx.ImageSize ( searchActiveImage )
2022-03-30 17:40:39 +02:00
activew = activew * activeResize
activeh = activeh * activeResize
local activeXPos = 0
local activeYStartPos = desh - sh - 722
2022-03-11 00:43:19 +01:00
2022-03-30 17:40:39 +02:00
local activeYPos = activeYStartPos + transitionSearchInfoOffsetY
gfx.ImageRect ( activeXPos , activeYPos , activew , activeh , searchActiveImage , 1 , 0 )
2021-12-18 21:39:47 +01:00
2022-03-09 09:24:21 +01:00
-- Draw Searchbox
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
local searchResize = 0.8
local tw , th = gfx.ImageSize ( searchBgImage )
tw = tw * searchResize
th = th * searchResize
local xPos = ( desw - tw ) / 2
local yStartPos = 170
2021-12-18 21:39:47 +01:00
2022-03-09 09:24:21 +01:00
local yPos = yStartPos - transitionSearchbarOffsetY
gfx.ImageRect ( xPos , yPos , tw , th , searchBgImage , 1 , 0 )
2022-03-30 17:40:39 +02:00
gfx.FontSize ( 48 )
2021-12-18 21:39:47 +01:00
gfx.LoadSkinFont ( ' Digital-Serial-Bold.ttf ' )
gfx.TextAlign ( gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE )
2022-03-30 17:40:39 +02:00
gfx.Text ( songwheel.searchText , xPos + 160 , yPos + 83.2 )
2021-08-05 22:01:17 +02:00
end
2022-03-16 05:51:53 +01:00
function drawScrollbar ( )
if isFilterWheelActive or transitionLeaveScale ~= 0 then return end
2022-03-16 08:24:02 +01:00
-- Scrollbar Background
2022-03-16 05:51:53 +01:00
gfx.BeginPath ( )
2022-03-30 17:40:39 +02:00
local resize = 0.85
local lw , lh = gfx.ImageSize ( scrollBarBackgroundImage )
local lw = lw * resize
local lh = lh * resize
2022-03-16 05:51:53 +01:00
local xPos = desw - 20
local backgroundYPos = desh / 2 - lh / 2
gfx.ImageRect ( xPos , backgroundYPos , lw , lh , scrollBarBackgroundImage , 1 , 0 )
2022-03-16 08:24:02 +01:00
-- Scrollbar Fill
2022-03-16 05:51:53 +01:00
gfx.BeginPath ( )
2022-03-30 17:40:39 +02:00
local sw , sh = gfx.ImageSize ( scrollBarFillImage )
local sw = sw * resize
local sh = sh * resize
local fillXPos = xPos - 6
local minScrollYPos = backgroundYPos
local maxScrollYPos = backgroundYPos + lh - sh
local scrollStep = ( maxScrollYPos - minScrollYPos ) / ( # songwheel.songs - 1 )
local scrollbarYOffset = ( selectedIndex - 1 ) * scrollStep
local scrollbarYPos = minScrollYPos + scrollbarYOffset
gfx.ImageRect ( fillXPos , scrollbarYPos , sw , sh , scrollBarFillImage , 1 , 0 )
2022-03-16 05:51:53 +01:00
2022-03-16 08:24:02 +01:00
-- 1st letter of song title on scroll
gfx.BeginPath ( )
gfx.FontSize ( 16 )
gfx.LoadSkinFont ( ' Digital-Serial-Bold.ttf ' )
gfx.Rect ( fillXPos - 18 , scrollbarYPos - 5 , 16 , 16 )
gfx.FillColor ( 0 , 0 , 0 , 170 )
gfx.Fill ( )
gfx.FillColor ( 255 , 255 , 255 )
gfx.TextAlign ( gfx.TEXT_ALIGN_MIDDLE + gfx.TEXT_ALIGN_CENTER )
2022-03-23 23:52:06 +01:00
if ( songwheel.songs [ selectedIndex ] ~= nil ) then
2022-03-30 17:40:39 +02:00
local letter = string.upper ( common.firstLetter ( songwheel.songs [ selectedIndex ] . title ) )
gfx.Text ( letter , fillXPos - 10 , scrollbarYPos + 5 )
2022-03-23 23:52:06 +01:00
end
2021-08-05 22:01:17 +02:00
end
2021-12-16 18:01:33 +01:00
function refreshIrLeaderboard ( deltaTime )
2021-12-16 18:29:04 +01:00
if not IRData.Active then
2022-03-30 17:40:39 +02:00
return
2021-12-16 18:29:04 +01:00
end
2021-12-16 20:49:11 +01:00
2021-12-16 17:31:38 +01:00
if irRequestStatus ~= 1 then -- Only continue if the leaderboard is requesteded, but not loading or loaded.
2021-12-14 19:08:46 +01:00
return
end
irLeaderboard = { }
2022-03-30 17:40:39 +02:00
local song = songwheel.songs [ selectedIndex ]
local diff = song and song.difficulties [ selectedDifficulty ] or false
2021-12-14 19:08:46 +01:00
if ( not diff ) then
2022-03-30 17:40:39 +02:00
return
2021-12-14 19:08:46 +01:00
end
2021-12-16 18:01:33 +01:00
if ( irLeaderboardsCache [ diff.hash ] ) then
2022-03-30 17:40:39 +02:00
irLeaderboard = irLeaderboardsCache [ diff.hash ]
irRequestStatus = 20
return
2021-12-16 18:01:33 +01:00
end
if ( irRequestTimeout > 0 ) then
irRequestTimeout = irRequestTimeout - deltaTime
2022-03-30 17:40:39 +02:00
return
2021-12-16 18:01:33 +01:00
end
2022-03-30 17:40:39 +02:00
irRequestStatus = 2 -- Loading
2021-12-16 17:31:38 +01:00
-- onIrLeaderboardFetched({
-- statusCode = 20,
-- body = {}
-- })
2021-12-14 19:08:46 +01:00
IR.Leaderboard ( diff.hash , ' best ' , 4 , onIrLeaderboardFetched )
end
function dump ( o )
if type ( o ) == ' table ' then
local s = ' { '
for k , v in pairs ( o ) do
if type ( k ) ~= ' number ' then k = ' " ' .. k .. ' " ' end
s = s .. ' [ ' .. k .. ' ] = ' .. dump ( v ) .. ' , '
end
return s .. ' } '
else
return tostring ( o )
end
end
function onIrLeaderboardFetched ( res )
2022-03-30 17:40:39 +02:00
irRequestStatus = res.statusCode
2021-12-16 16:52:03 +01:00
2022-03-30 17:40:39 +02:00
local song = songwheel.songs [ selectedIndex ]
local diff = song and song.difficulties [ selectedDifficulty ] or false
2021-12-16 20:49:11 +01:00
game.Log ( diff.hash , game.LOGGER_ERROR )
2021-12-14 19:08:46 +01:00
if res.statusCode == IRData.States . Success then
2021-12-16 20:49:11 +01:00
game.Log ( ' Raw IR reposonse: ' .. dump ( res.body ) , game.LOGGER_ERROR )
2022-03-30 17:40:39 +02:00
local tempIrLB = res.body
2021-12-14 22:22:38 +01:00
2021-12-16 20:49:11 +01:00
table.sort ( tempIrLB , function ( a , b )
-- game.Log(a.score .. ' ?? ' .. b.score, game.LOGGER_ERROR)
return a.score > b.score
end )
-- for i, tempScore in ipairs(tempIrLeaderboard) do
-- irLeaderboard[tempScore.ranking] = tempScore
-- end
2021-12-14 22:22:38 +01:00
2022-03-30 17:40:39 +02:00
irLeaderboard = tempIrLB
irLeaderboardsCache [ diff.hash ] = irLeaderboard
2021-12-16 18:01:33 +01:00
2021-12-14 19:08:46 +01:00
game.Log ( dump ( irLeaderboard ) , game.LOGGER_ERROR )
else
game.Log ( " IR error " .. res.statusCode , game.LOGGER_ERROR )
end
end
2021-07-30 21:34:36 +02:00
function tickTransitions ( deltaTime )
if transitionScrollScale < 1 then
transitionScrollScale = transitionScrollScale + deltaTime / 0.1 -- transition should last for that time in seconds
else
transitionScrollScale = 1
end
2021-07-31 22:14:34 +02:00
if transitionAfterscrollScale < 1 then
if transitionScrollScale == 1 then
-- Only start the after scroll transition when the scroll transition is finished
2021-08-01 18:08:52 +02:00
transitionAfterscrollScale = transitionAfterscrollScale + deltaTime / 15
2021-07-31 22:14:34 +02:00
end
else
2022-03-30 17:40:39 +02:00
transitionAfterscrollScale = 1
2021-07-31 22:14:34 +02:00
end
2021-07-30 21:34:36 +02:00
if scrollingUp then
2022-03-30 17:40:39 +02:00
transitionScrollOffsetY = Easing.inQuad ( 1 - transitionScrollScale ) * songPlateHeight
2021-07-30 21:34:36 +02:00
else
2022-03-30 17:40:39 +02:00
transitionScrollOffsetY = Easing.inQuad ( 1 - transitionScrollScale ) * - songPlateHeight
2021-07-30 21:34:36 +02:00
end
2021-07-31 22:14:34 +02:00
2021-08-01 18:08:52 +02:00
if transitionAfterscrollScale < 0.02 then
transitionAfterscrollDataOverlayAlpha = math.min ( 1 , transitionAfterscrollScale / 0.02 )
2021-07-31 22:14:34 +02:00
else
2022-03-30 17:40:39 +02:00
transitionAfterscrollDataOverlayAlpha = 1
2021-07-31 22:14:34 +02:00
end
2022-03-09 09:24:21 +01:00
-- Searchbar offsets and alpha
if not searchPreviousActiveState then
if transitionSearchEnterScale > 0 then
transitionSearchEnterScale = transitionSearchEnterScale - deltaTime / 0.5 -- transition should last for that time in seconds
else
transitionSearchEnterScale = 0
end
else
if transitionSearchEnterScale < 1 then
transitionSearchEnterScale = transitionSearchEnterScale + deltaTime / 0.5 -- transition should last for that time in seconds
else
transitionSearchEnterScale = 1
end
end
2022-03-11 00:43:19 +01:00
2022-03-09 09:24:21 +01:00
transitionSearchInfoOffsetY = Easing.inOutQuad ( 1 - transitionSearchEnterScale ) * 1680
transitionSearchbarOffsetY = Easing.inOutQuad ( 1 - transitionSearchEnterScale ) * 300
transitionSearchBackgroundAlpha = Easing.inOutQuad ( transitionSearchEnterScale )
2022-03-11 00:43:19 +01:00
if not searchInfoPreviousActiveState then
if transitionSearchInfoEnterScale > 0 then
transitionSearchInfoEnterScale = transitionSearchInfoEnterScale - deltaTime / 0.25 -- transition should last for that time in seconds
else
transitionSearchInfoEnterScale = 0
end
else
if transitionSearchInfoEnterScale < 1 then
transitionSearchInfoEnterScale = transitionSearchInfoEnterScale + deltaTime / 0.25 -- transition should last for that time in seconds
else
transitionSearchInfoEnterScale = 1
end
end
transitionSearchBackgroundInfoAlpha = Easing.inOutQuad ( transitionSearchInfoEnterScale )
2021-07-31 22:14:34 +02:00
-- Grade alpha
2021-08-01 18:08:52 +02:00
if transitionAfterscrollScale >= 0.03 and transitionAfterscrollScale < 0.033 then
2022-03-30 17:40:39 +02:00
transitionAfterscrollGradeAlpha = 0.5
2021-08-01 18:08:52 +02:00
elseif transitionAfterscrollScale >= 0.04 then
2022-03-30 17:40:39 +02:00
transitionAfterscrollGradeAlpha = 1
2021-07-31 22:14:34 +02:00
else
2022-03-30 17:40:39 +02:00
transitionAfterscrollGradeAlpha = 0
2021-07-31 22:14:34 +02:00
end
-- Badge alpha
2021-08-01 18:08:52 +02:00
if transitionAfterscrollScale >= 0.032 and transitionAfterscrollScale < 0.035 then
2022-03-30 17:40:39 +02:00
transitionAfterscrollBadgeAlpha = 0.5
2021-08-01 18:08:52 +02:00
elseif transitionAfterscrollScale >= 0.042 then
2022-03-30 17:40:39 +02:00
transitionAfterscrollBadgeAlpha = 1
2021-07-31 22:14:34 +02:00
else
2022-03-30 17:40:39 +02:00
transitionAfterscrollBadgeAlpha = 0
2021-07-31 22:14:34 +02:00
end
2021-08-01 18:08:52 +02:00
-- Song title alpha and pos
2021-08-06 20:06:35 +02:00
if transitionAfterscrollScale < 0.025 then
2022-03-30 17:40:39 +02:00
transitionAfterscrollTextSongTitle = Easing.outQuad ( math.min ( 1 , ( transitionAfterscrollScale ) / 0.025 ) )
2021-08-01 18:08:52 +02:00
else
transitionAfterscrollTextSongTitle = 1
end
-- Song artist alpha and pos
2021-08-06 20:06:35 +02:00
if transitionAfterscrollScale < 0.025 then
2022-03-30 17:40:39 +02:00
transitionAfterscrollTextSongArtist = Easing.outQuad ( math.min ( 1 , ( transitionAfterscrollScale ) / 0.025 ) )
2021-08-01 18:08:52 +02:00
else
transitionAfterscrollTextSongArtist = 1
end
2021-07-31 23:00:32 +02:00
-- Difficulties alpha
2021-08-01 18:08:52 +02:00
if transitionAfterscrollScale < 0.025 then
transitionAfterscrollDifficultiesAlpha = math.min ( 1 , transitionAfterscrollScale / 0.025 )
2021-07-31 23:00:32 +02:00
else
2022-03-30 17:40:39 +02:00
transitionAfterscrollDifficultiesAlpha = 1
2021-07-31 23:00:32 +02:00
end
2021-08-01 18:08:52 +02:00
2021-08-26 19:50:33 +02:00
-- Jacket bg animation
if transitionJacketBgScrollScale < 1 then
transitionJacketBgScrollScale = transitionJacketBgScrollScale + deltaTime / 20 -- transition should last for that time in seconds
2021-08-01 18:08:52 +02:00
else
2021-08-26 19:50:33 +02:00
transitionJacketBgScrollScale = 0
2021-08-01 18:08:52 +02:00
end
2021-08-12 16:55:10 +02:00
2021-08-26 19:50:33 +02:00
if transitionJacketBgScrollScale < 0.05 or transitionJacketBgScrollScale >= 1 then
2022-03-30 17:40:39 +02:00
transitionJacketBgScrollAlpha = 0
2021-08-26 19:50:33 +02:00
elseif transitionJacketBgScrollScale >= 0.05 and transitionJacketBgScrollScale < 0.1 then
2022-03-30 17:40:39 +02:00
transitionJacketBgScrollAlpha = math.min ( 1 , ( transitionJacketBgScrollScale - 0.05 ) / 0.05 )
2021-08-26 19:50:33 +02:00
elseif transitionJacketBgScrollScale >= 0.8 and transitionJacketBgScrollScale < 1 then
transitionJacketBgScrollAlpha = math.max ( 0 ,
math.min ( 1 , 1 - ( ( transitionJacketBgScrollScale - 0.8 ) / 0.05 ) )
2022-03-30 17:40:39 +02:00
)
2021-08-26 19:50:33 +02:00
else
2022-03-30 17:40:39 +02:00
transitionJacketBgScrollAlpha = 1
2021-08-26 19:50:33 +02:00
end
2022-03-30 17:40:39 +02:00
transitionJacketBgScrollPosX = 0 + ( transitionJacketBgScrollScale * ( 0.8 / 1 ) ) *- 300
2021-08-26 19:50:33 +02:00
2021-08-16 16:29:21 +02:00
-- Laser anim
if transitionLaserScale < 1 then
2021-08-18 18:41:33 +02:00
transitionLaserScale = transitionLaserScale + deltaTime / 2 -- transition should last for that time in seconds
2021-08-16 16:29:21 +02:00
else
transitionLaserScale = 0
end
2022-03-30 17:40:39 +02:00
transitionLaserY = desh - math.min ( transitionLaserScale * 2 * desh , desh )
2021-08-16 16:29:21 +02:00
2021-08-26 15:31:28 +02:00
-- Flash transition
if transitionFlashScale < 1 then
2022-03-30 17:40:39 +02:00
local songBpm = 120
2021-08-26 19:04:20 +02:00
if ( songwheel.songs [ selectedIndex ] and game.GetSkinSetting ( ' animations_affectWithBPM ' ) ) then
2022-03-30 17:40:39 +02:00
songBpm = songwheel.songs [ selectedIndex ] . bpm
2021-08-26 15:31:28 +02:00
-- Is a variable BPM
if ( type ( songBpm ) == " string " ) then
2022-03-30 17:40:39 +02:00
local s = split ( songBpm , ' - ' )
songBpm = tonumber ( s [ 1 ] ) -- Lowest bpm value
2021-08-26 15:31:28 +02:00
end
end
2021-08-27 21:31:46 +02:00
-- If the original songBpm is "2021.04.01" for example, the above code can produce `nil` in the songBpm
-- since it cannot parse the number out of that string. Here we implement a fallback, to not crash
-- USC on whacky charts. Whacky charters, quit using batshit insane bpm values. It makes me angery >:(
if ( songBpm == nil ) then
2022-03-30 17:40:39 +02:00
songBpm = 120
2021-08-27 21:31:46 +02:00
end
2021-08-26 15:31:28 +02:00
transitionFlashScale = transitionFlashScale + deltaTime / ( 60 / songBpm ) -- transition should last for that time in seconds
else
transitionFlashScale = 0
end
if transitionFlashScale < 0.5 then
2022-03-30 17:40:39 +02:00
transitionFlashAlpha = transitionFlashScale * 2
2021-08-26 15:31:28 +02:00
else
2022-03-30 17:40:39 +02:00
transitionFlashAlpha = 1 - ( ( transitionFlashScale - 0.5 ) * 2 )
2021-08-26 15:31:28 +02:00
end
transitionFlashAlpha = 1 + transitionFlashAlpha * 0.5
2021-08-12 16:55:10 +02:00
-- Leave transition
2021-11-20 19:12:12 +01:00
if ( isFilterWheelActive ) then
2021-08-12 17:18:35 +02:00
if transitionLeaveScale < 1 then
2021-11-20 19:12:12 +01:00
transitionLeaveScale = transitionLeaveScale + deltaTime / TRANSITION_LEAVE_DURATION -- transition should last for that time in seconds
2021-08-12 17:18:35 +02:00
else
transitionLeaveScale = 1
end
2022-03-30 17:40:39 +02:00
transitionLeaveReappearTimer = 1
transitionAfterscrollScale = 0 -- Keep songwheel in the "afterscroll" state while the filterwheel is active
transitionJacketBgScrollScale = 0 -- Same thing here, just with the jacket bg
2021-11-20 19:12:12 +01:00
else
2021-11-20 19:34:15 +01:00
if ( transitionLeaveReappearTimer ~= 0 ) then
2022-03-30 17:40:39 +02:00
transitionAfterscrollScale = 0 -- Keep songwheel in the "afterscroll" state while we're waiting on filter wheel to fade out
transitionJacketBgScrollScale = 0 -- Same thing here, just with the jacket bg
2021-11-20 19:12:12 +01:00
end
2021-11-20 19:27:28 +01:00
transitionLeaveReappearTimer = transitionLeaveReappearTimer - deltaTime / ( TRANSITION_LEAVE_DURATION + 0.05 ) -- 0.05s is a few frames between the completetion of the fade out and songs reappearing in the AC
2021-08-12 16:55:10 +02:00
2021-11-20 19:12:12 +01:00
if ( transitionLeaveReappearTimer <= 0 ) then
2022-03-30 17:40:39 +02:00
transitionLeaveScale = 0
transitionLeaveReappearTimer = 0
2021-11-20 19:12:12 +01:00
end
end
2021-07-30 21:34:36 +02:00
end
2022-03-30 17:40:39 +02:00
draw_songwheel = function ( deltaTime )
drawBackground ( deltaTime )
2021-07-25 20:10:06 +02:00
2021-07-30 16:37:01 +02:00
drawSongList ( )
2021-07-25 20:10:06 +02:00
2022-03-30 17:40:39 +02:00
isFilterWheelActive = game.GetSkinSetting ( ' _songWheelOverlayActive ' ) == 1
2021-11-20 19:12:12 +01:00
2021-07-31 20:36:05 +02:00
drawData ( )
2021-11-20 19:27:28 +01:00
drawCursor ( )
2021-07-31 20:36:05 +02:00
2021-08-13 17:35:26 +02:00
drawFilterInfo ( deltaTime )
2022-03-30 17:40:39 +02:00
drawSearch ( )
2021-08-05 22:01:17 +02:00
2022-03-30 17:40:39 +02:00
drawScrollbar ( )
2022-03-16 05:51:53 +01:00
2022-03-30 17:40:39 +02:00
gfx.BeginPath ( )
2021-07-30 16:37:01 +02:00
gfx.FontSize ( 18 )
gfx.TextAlign ( gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_TOP )
2021-07-30 21:34:36 +02:00
local debugScrollingUp = " FALSE "
2022-03-30 17:40:39 +02:00
if scrollingUp then debugScrollingUp = " TRUE " end
2022-02-17 18:06:25 +01:00
if game.GetSkinSetting ( ' debug_showInformation ' ) then
2022-03-30 17:40:39 +02:00
gfx.Text ( ' S_I: ' .. selectedIndex .. ' // S_D: ' .. selectedDifficulty .. ' // S_UP: ' .. debugScrollingUp .. ' // AC_TS: ' .. transitionAfterscrollScale .. ' // L_TS: ' .. transitionLeaveScale .. ' // IR_CODE: ' .. irRequestStatus .. ' // IR_T: ' .. irRequestTimeout , 8 , 8 )
2022-02-17 18:06:25 +01:00
end
2021-11-22 20:23:34 +01:00
2022-03-30 17:40:39 +02:00
gfx.ResetTransform ( )
2021-11-22 20:23:34 +01:00
end
render = function ( deltaTime )
2022-03-30 17:40:39 +02:00
tickTransitions ( deltaTime )
2021-11-22 20:23:34 +01:00
game.SetSkinSetting ( ' _currentScreen ' , ' songwheel ' )
2022-03-30 17:40:39 +02:00
Sound.stopMusic ( )
2021-11-22 20:23:34 +01:00
2022-03-30 17:40:39 +02:00
Dim.updateResolution ( )
2021-11-22 20:23:34 +01:00
2022-03-30 17:40:39 +02:00
Wallpaper.render ( )
2021-11-22 20:23:34 +01:00
2022-03-30 17:40:39 +02:00
Dim.transformToScreenSpace ( )
2021-12-14 19:08:46 +01:00
2022-03-30 17:40:39 +02:00
draw_songwheel ( deltaTime )
refreshIrLeaderboard ( deltaTime )
2021-07-25 20:10:06 +02:00
end
2021-08-12 21:21:42 +02:00
songs_changed = function ( withAll )
2021-12-16 18:17:48 +01:00
irLeaderboardsCache = { } -- Reset LB cache
2021-08-12 21:21:42 +02:00
if not withAll then return end
2021-08-27 20:18:55 +02:00
game.SetSkinSetting ( ' _songWheelScrollbarTotal ' , # songwheel.songs )
game.SetSkinSetting ( ' _songWheelScrollbarIndex ' , selectedIndex )
2021-08-12 21:21:42 +02:00
local diffs = { }
for i = 1 , # songwheel.allSongs do
local song = songwheel.allSongs [ i ]
for j = 1 , # song.difficulties do
local diff = song.difficulties [ j ]
diff.force = VolforceCalc.calc ( diff )
table.insert ( diffs , diff )
end
end
table.sort ( diffs , function ( l , r )
return l.force > r.force
end )
totalForce = 0
for i = 1 , 50 do
if diffs [ i ] then
2022-03-30 17:40:39 +02:00
top50diffs [ diffs [ i ] . id ] = true
2021-08-12 21:21:42 +02:00
totalForce = totalForce + diffs [ i ] . force
end
end
game.SetSkinSetting ( ' _volforce ' , totalForce )
end
2021-07-25 20:10:06 +02:00
set_index = function ( newIndex )
2022-03-30 17:40:39 +02:00
transitionScrollScale = 0
transitionAfterscrollScale = 0
transitionJacketBgScrollScale = 0
2021-07-30 21:34:36 +02:00
2021-08-27 20:18:55 +02:00
game.SetSkinSetting ( ' _songWheelScrollbarTotal ' , # songwheel.songs )
game.SetSkinSetting ( ' _songWheelScrollbarIndex ' , newIndex )
2022-03-30 17:40:39 +02:00
scrollingUp = false
2021-07-30 21:34:36 +02:00
if ( ( newIndex > selectedIndex and not ( newIndex == # songwheel.songs and selectedIndex == 1 ) ) or ( newIndex == 1 and selectedIndex == # songwheel.songs ) ) then
2022-03-30 17:40:39 +02:00
scrollingUp = true
end
2021-07-30 21:34:36 +02:00
2022-03-30 17:40:39 +02:00
game.PlaySample ( ' song_wheel/cursor_change.wav ' )
2021-07-30 21:34:36 +02:00
2022-03-30 17:40:39 +02:00
selectedIndex = newIndex
end
2021-07-25 20:10:06 +02:00
set_diff = function ( newDiff )
2021-08-12 14:29:55 +02:00
if newDiff ~= selectedDifficulty then
2022-03-30 17:40:39 +02:00
jacketCache = { } -- Clear the jacket cache for the new diff jackets
2021-08-13 22:36:21 +02:00
2022-03-30 17:40:39 +02:00
game.PlaySample ( ' song_wheel/diff_change.wav ' )
2021-08-12 14:29:55 +02:00
end
2022-03-30 17:40:39 +02:00
selectedDifficulty = newDiff
2021-12-14 20:02:25 +01:00
irLeaderboard = { }
2022-03-30 17:40:39 +02:00
irRequestStatus = 1
2021-12-14 20:02:25 +01:00
irRequestTimeout = 2
2022-03-30 17:40:39 +02:00
end