diff --git a/BGAnimations/Screen in.lua b/BGAnimations/Screen in.lua index c4441a65..50df95a5 100644 --- a/BGAnimations/Screen in.lua +++ b/BGAnimations/Screen in.lua @@ -2,11 +2,11 @@ local t = Def.ActorFrame{} t[#t+1] = Def.Quad{ InitCommand=function(self) - self:FullScreen():diffuse(getMainColor("background")):diffusealpha(1) - end; + self:FullScreen():diffuse(getMainColor("transition")):diffusealpha(0):smooth(0.1):diffusealpha(1) + end, OnCommand=function(self) - self:smooth(0.2):diffusealpha(0) - end; + self:smooth(0.1):diffusealpha(0) + end } return t \ No newline at end of file diff --git a/BGAnimations/Screen out.lua b/BGAnimations/Screen out.lua index 60071750..b4b5a82e 100644 --- a/BGAnimations/Screen out.lua +++ b/BGAnimations/Screen out.lua @@ -3,10 +3,10 @@ local t = Def.ActorFrame{} t[#t+1] = Def.Quad{ InitCommand=function(self) self:FullScreen():diffuse(getMainColor("background")):diffusealpha(0) - end; + end, OnCommand=function(self) self:smooth(0.2):diffusealpha(1) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenChartLeaderboard decorations/default.lua b/BGAnimations/ScreenChartLeaderboard decorations/default.lua new file mode 100644 index 00000000..a8235dec --- /dev/null +++ b/BGAnimations/ScreenChartLeaderboard decorations/default.lua @@ -0,0 +1,3 @@ +local t = Def.ActorFrame{} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenDownload in.lua b/BGAnimations/ScreenChartLeaderboard out.lua similarity index 100% rename from BGAnimations/ScreenDownload in.lua rename to BGAnimations/ScreenChartLeaderboard out.lua diff --git a/BGAnimations/ScreenChartLeaderboard overlay/default.lua b/BGAnimations/ScreenChartLeaderboard overlay/default.lua new file mode 100644 index 00000000..3367fce0 --- /dev/null +++ b/BGAnimations/ScreenChartLeaderboard overlay/default.lua @@ -0,0 +1,1359 @@ +local pn = GAMESTATE:GetEnabledPlayers()[1] +local song = GAMESTATE:GetCurrentSong() +local steps = GAMESTATE:GetCurrentSteps(pn) +local stepsType = steps:GetStepsType() + +local scoreList = {} +local maxItems = 10 +local maxPages = math.ceil(#scoreList/maxItems) +local curPage = 1 +local currentCountry = "Global" + +local lbActor +local cheatIndex +local inDetail = false + +local validStepsType = { + 'StepsType_Dance_Single', + 'StepsType_Dance_Solo', + 'StepsType_Dance_Double', +} +local maxNumDifficulties = 0 +for _,st in pairs(validStepsType) do + maxNumDifficulties = math.max(maxNumDifficulties, #song:GetStepsByStepsType(st)) +end + +local filts = {"All Rates", "Current Rate"} +local topfilts = {"Top Scores", "All Scores"} + +local function getNextStepsType(n) + for i = 1, #validStepsType do + if validStepsType[i] == stepsType then + stepsType = validStepsType[(i+n-1+#validStepsType)%#validStepsType+1] -- 1 index scks + return stepsType + end + end +end + +local function movePage(n) + if n > 0 then + curPage = ((curPage+n-1) % maxPages + 1) + else + curPage = ((curPage+n+maxPages-1) % maxPages+1) + end + MESSAGEMAN:Broadcast("UpdateCLBList") +end + +local function meterComparator(stepA, stepB) + local diffA = stepA:GetDifficulty() + local diffB = stepB:GetDifficulty() + + return Enum.Reverse(Difficulty)[diffA] < Enum.Reverse(Difficulty)[diffB] +end + +local function updateLeaderBoardForCurrentChart() + if steps then + DLMAN:RequestChartLeaderBoardFromOnline( + steps:GetChartKey(), + function(leaderboard) + lbActor:queuecommand("SetFromLeaderboard", leaderboard) + end + ) + else + lbActor:queuecommand("SetFromLeaderboard", {}) + end +end + + +local function input(event) + + if event.type == "InputEventType_FirstPress" then + if event.button == "Back" or event.button == "Start" then + SCREENMAN:GetTopScreen():Cancel() + end + + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + end + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + end + + if event.button == "EffectUp" and not inDetail then + changeMusicRate(0.05) + elseif event.button == "EffectDown" and not inDetail then + changeMusicRate(-0.05) + elseif event.button == "MenuLeft" and not inDetail then + movePage(-1) + elseif event.button == "MenuRight" and not inDetail then + movePage(1) + end + end + return false + +end + +local top +local frameWidth = 430 +local frameHeight = 340 + +local verticalSpacing = 7 +local horizontalSpacing = 10 + +local function topRow() + local frameWidth = SCREEN_WIDTH - 20 + local frameHeight = 40 + + local t = Def.ActorFrame{ + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + end + } + + t[#t+1] = Def.Sprite { + Name = "Banner", + InitCommand = function(self) + self:x(-frameWidth/2 + 5) + self:halign(0) + local bnpath = song:GetBannerPath() + if not bnpath then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) + self:scaletoclipped(96, 30) + end + } + + t[#t+1] = LoadFont("Common BLarge") .. { + Name = "SongTitle", + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, -9) + self:zoom(0.25) + self:halign(0) + self:settext(song:GetMainTitle()) + if #song:GetDisplaySubTitle() == 0 then + self:zoom(0.35):y(-5) + end + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + local actor = self:GetParent():GetChild("SongTitle") + local x = actor:GetX() + actor:GetWidth()*actor:GetZoomX() + 2 + local y = actor:GetY() - 2 + + self:xy(x,y) + self:zoom(0.3) + self:halign(0) + self:playcommand("Set") + end, + SetCommand = function(self) + local length = song:GetStepsSeconds()/getCurRateValue() + self:settextf("%s",SecondsToMSS(length)) + self:diffuse(getSongLengthColor(length)) + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 1) + self:zoom(0.35) + self:halign(0) + self:settext(song:GetDisplaySubTitle()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 9) + self:zoom(0.35) + self:halign(0) + self:settext("// "..song:GetDisplayArtist()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,-1) + self:zoom(0.5) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local diff = curSteps:GetDifficulty() + local stype = curSteps:GetStepsType() + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + meter = curSteps:GetMeter() + end + + local difftext + if diff == 'Difficulty_Edit' then + difftext = curSteps:GetDescription() + difftext = difftext == '' and getDifficulty(diff) or difftext + else + difftext = getDifficulty(diff) + end + + self:settext(ToEnumShortString(stype):gsub("%_"," ").." "..difftext.." "..meter) + self:diffuse(getDifficultyColor(GetCustomDifficulty(stype,diff))) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,9) + self:zoom(0.35) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local notes = 0 + if curSteps ~= nil then + notes = curSteps:GetRadarValues(pn):GetValue("RadarCategory_Notes") + end + self:settextf("%d Notes", notes) + self:diffuse(Saturation(getDifficultyColor(GetCustomDifficulty(curSteps:GetStepsType(),curSteps:GetDifficulty())),0.3)) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name="MSDAvailability", + InitCommand = function(self) + self:xy(frameWidth/2-5,-11) + self:zoom(0.30) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + if curSteps ~= nil then + + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + self:settext("Default") + self:diffuse(color(colorConfig:get_data().main.disabled)) + else + self:settext("MSD") + self:diffuse(color(colorConfig:get_data().main.enabled)) + end + end + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "round_star")) .. { + InitCommand = function(self) + self:xy(-frameWidth/2+1,-frameHeight/2+1) + self:zoom(0.3) + self:wag() + self:diffuse(Color.Yellow) + + if not song:IsFavorited() then + self:visible(false) + end + end + } + + return t +end + +local function stepsListRow() + local frameWidth = 150 + local frameHeight = 25 + local topRowFrameWidth = SCREEN_WIDTH - 20 + local topRowFrameHeight = 40 + + + local stepsTable = {} + local t = Def.ActorFrame{ + SetStepsTypeMessageCommand = function(self, params) + stepsTable = song:GetStepsByStepsType(params.st) + table.sort(stepsTable, meterComparator) + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:xy(-topRowFrameWidth/2, topRowFrameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(0) + end + + } + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(-topRowFrameWidth/2, topRowFrameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(0) + self:faderight(0.5) + end, + TopPressedCommand = function(self, params) + MESSAGEMAN:Broadcast("SetStepsType", {st = getNextStepsType(-1)}) + self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(-topRowFrameWidth/2+frameWidth/2, topRowFrameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(0) + self:fadeleft(0.5) + end, + TopPressedCommand = function(self, params) + MESSAGEMAN:Broadcast("SetStepsType", {st = getNextStepsType(1)}) + self:GetParent():GetChild("TriangleRight"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleLeft", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(-topRowFrameWidth/2+10,topRowFrameHeight) + self:rotationz(-90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleRight", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(-topRowFrameWidth/2+frameWidth-10,topRowFrameHeight) + self:rotationz(90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:zoom(0.4) + self:xy(-topRowFrameWidth/2+frameWidth/2,topRowFrameHeight) + end, + SetCommand = function(self) + self:settext(ToEnumShortString(stepsType):gsub("%_"," ")) + end + } + + for i = 1, maxNumDifficulties do + + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(40, frameHeight) + self:y(topRowFrameHeight) + self:diffuse(color("#000000")):diffusealpha(0) + self:halign(0) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) + end, + SetCommand = function(self) + local curSteps = stepsTable[i] + if curSteps then + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowCommand = function(self) + self:y(topRowFrameHeight) + self:finishtweening() + self:sleep((i-1)*0.03) + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)) + self:diffusealpha(0.8) + end, + HideCommand = function(self) + self:diffusealpha(0) + self:y(SCREEN_HEIGHT*10) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) + end, + TopPressedCommand = function(self) + MESSAGEMAN:Broadcast("SetSteps", {steps = stepsTable[i]}) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + local stype = steps:GetStepsType() + self:zoom(0.4) + self:diffusealpha(0) + self:xy((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10, topRowFrameHeight) + self:settext("0") + end, + SetCommand = function(self) + local curSteps = stepsTable[i] + if curSteps then + + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + meter = curSteps:GetMeter() + end + + self:settext(meter) + self:diffuse(color(colorConfig:get_data().difficulty[curSteps:GetDifficulty()])) + self:diffusealpha(0) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowCommand = function(self) + self:finishtweening() + self:sleep((i-1)*0.05) + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:finishtweening() + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10) + self:diffusealpha(0) + end + } + end + + return t +end + +local function stepsBPMRow() + local topRowFrameWidth = 0 + local topRowFrameHeight = 40 + local frameWidth = 150 + local frameHeight = 25 + local t = Def.ActorFrame{} + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, 25) + self:xy(topRowFrameWidth, topRowFrameHeight + frameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(1) + end + } + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(topRowFrameWidth/2-frameWidth/2, topRowFrameHeight + frameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:faderight(0.5) + end, + TopPressedCommand = function(self, params) + changeMusicRate(-0.05) + self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(topRowFrameWidth/2, topRowFrameHeight + frameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:fadeleft(0.5) + end, + TopPressedCommand = function(self, params) + changeMusicRate(0.05) + self:GetParent():GetChild("TriangleRight"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleLeft", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(topRowFrameWidth/2-frameWidth+10,topRowFrameHeight + frameHeight) + self:rotationz(-90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleRight", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(topRowFrameWidth/2-10,topRowFrameHeight + frameHeight) + self:rotationz(90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:zoom(0.35) + self:xy(topRowFrameWidth/2-75,topRowFrameHeight-4 + frameHeight) + end, + SetStepsMessageCommand = function(self, params) + if params.steps then + local bpms = steps:GetTimingData():GetActualBPM() + if bpms[1] == bpms[2] and bpms[1]~= nil then + self:settext(string.format("BPM: %d",bpms[1]*getCurRateValue())) + else + self:settext(string.format("BPM: %d-%d (%d)",bpms[1]*getCurRateValue(),bpms[2]*getCurRateValue(),getCommonBPM(song:GetTimingData():GetBPMsAndTimes(true),song:GetLastBeat()))) + end + end + end + } + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:zoom(0.3) + self:xy(topRowFrameWidth/2-75,topRowFrameHeight+4 + frameHeight) + end, + SetStepsMessageCommand = function(self, params) + self:settext(getCurRateDisplayString()) + end + } + + return t +end + + +local function offsetInput(event) + if event.type == "InputEventType_FirstPress" and inDetail then + local outputName = "" + if event.button == "EffectUp" then + outputName = "NextJudge" + elseif event.button == "EffectDown" then + outputName = "PrevJudge" + elseif event.button == "MenuDown" then + outputName = "ToggleHands" + elseif event.button == "MenuUp" then + outputName = "ResetJudge" + end + + if outputName ~= "" then + MESSAGEMAN:Broadcast("OffsetPlotModification", {Name = outputName}) + end + end +end + + +local function scoreList() + local frameWidth = 430 + local frameHeight = 340 + local t = Def.ActorFrame{ + SetStepsMessageCommand = function(self, params) + steps = params.steps + scoreList = DLMAN:GetChartLeaderBoard(steps:GetChartKey(), currentCountry) + if #scoreList == 0 then + updateLeaderBoardForCurrentChart() + end + curPage = 1 + if scoreList ~= nil then + maxPages = math.ceil(#scoreList/maxItems) + MESSAGEMAN:Broadcast("UpdateCLBList") + self:GetChild("NoScore"):visible(false) + else + maxPages = 1 + self:RunCommandsOnChildren(function(self) self:playcommand("Hide") end) + self:GetChild("NoScore"):visible(true):playcommand("Set") + end + end, + SetFromLeaderboardCommand = function(self, leaderboard) + scoreList = DLMAN:GetChartLeaderBoard(steps:GetChartKey(), currentCountry) + curPage = 1 + if scoreList ~= nil then + maxPages = math.ceil(#scoreList/maxItems) + MESSAGEMAN:Broadcast("UpdateCLBList") + self:GetChild("NoScore"):visible(false) + else + maxPages = 1 + self:RunCommandsOnChildren(function(self) self:playcommand("Hide") end) + self:GetChild("NoScore"):visible(true):playcommand("Set") + end + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name = "NoScore", + InitCommand = function(self) + self:xy(frameWidth/2, frameHeight/2) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.6) + self:settext("No scores here!\n(* ` ω´)") + end, + SetCommand = function(self) + self:finishtweening() + self:y(frameHeight/2-5) + self:easeOut(0.5) + self:y(frameHeight/2) + end + } + + local scoreItemWidth = frameWidth-30 + local scoreItemHeight = 25 + + local scoreItemX = 20 + local scoreItemY = 30+scoreItemHeight/2 + local scoreItemYSpacing = 5 + + local function scoreListItem(i) + local scoreIndex = (curPage-1)*10+i + local detail = false + local hs + + local t = Def.ActorFrame{ + InitCommand = function(self) + self:diffusealpha(0) + self:xy(scoreItemX, scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)-10) + end, + ShowCommand = function(self) + self:y(scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)-10) + self:diffusealpha(0) + self:finishtweening() + self:sleep((i-1)*0.03) + self:easeOut(1) + self:y(scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + self:y(SCREEN_HEIGHT*10) -- Throw it offscreen + end, + UpdateCLBListMessageCommand = function(self) + detail = false + scoreIndex = (curPage-1)*10+i + hs = scoreList[scoreIndex] + + if scoreList ~= nil and scoreList[scoreIndex] ~= nil then + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + if params.index == i then + detail = true + self:finishtweening() + self:easeOut(0.5) + self:y(scoreItemY) + self:valign(0) + else + self:playcommand("Hide") + end + end, + HideOnlineScoreDetailMessageCommand = function(self) + detail = false + if scoreList ~= nil and scoreList[scoreIndex] ~= nil then + self:playcommand("Show") + end + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(-10,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + end, + SetCommand = function(self) + self:settextf("%d", scoreIndex) + end + } + + t[#t+1] = quadButton(6) .. { + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(scoreItemWidth, scoreItemHeight) + end, + TopPressedCommand = function(self, params) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + if params.input == "DeviceButton_left mouse button" then + if not detail then + MESSAGEMAN:Broadcast("ShowOnlineScoreDetail", {index = i, scoreIndex = scoreIndex}) + end + elseif params.input == "DeviceButton_right mouse button" then + MESSAGEMAN:Broadcast("HideOnlineScoreDetail") + end + end, + SetCommand = function(self) + if scoreList[i]:GetEtternaValid() then + self:diffuse(color("#FFFFFF")) + else + self:diffuse(color(colorConfig:get_data().clearType.ClearType_Invalid)) + end + self:diffusealpha(0.2) + end + } + + t[#t+1] = getClearTypeLampQuad(3, scoreItemHeight)..{ + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.8) + end, + SetCommand = function(self) + self:playcommand("SetClearType", {clearType = getClearType(pn,steps,scoreList[scoreIndex])}) + end + } + + + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(20,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + local ssr = scoreList[scoreIndex]:GetSkillsetSSR("Overall") + self:settextf("%0.2f",ssr) + self:diffuse(getMSDColor(ssr)) + end + } + + t[#t+1] = LoadFont("Common Bold")..{ + Name = "DisplayName", + InitCommand = function(self) + self:xy(40,-6) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:halign(0) + end, + SetCommand = function(self) + if hs:GetChordCohesion() then + self:diffuse(color("#F0EEA6")) + else + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + end + self:settext(hs:GetDisplayName()) + end + + } + + t[#t+1] = LoadFont("Common Normal") .. { + Name = "RateString", + InitCommand = function(self) + self:xy(40,-6) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(0) + end, + SetCommand = function(self) + local ratestring = "("..string.format("%.2f", scoreList[scoreIndex]:GetMusicRate()):gsub("%.?0$", "") .. "x)" + self:settext(ratestring) + self:x(self:GetParent():GetChild("DisplayName"):GetX()+(self:GetParent():GetChild("DisplayName"):GetWidth()*0.4)+5) + end + } + t[#t+1] = LoadFont("Common Normal") .. { + Name = "CCON", + InitCommand = function(self) + self:xy(40,-6) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(0) + self:settext("(CC On)") + end, + SetCommand = function(self) + if hs:GetChordCohesion() then + self:visible(true) + else + self:visible(false) + end + local ratewidth = self:GetParent():GetChild("RateString"):GetX()+(self:GetParent():GetChild("RateString"):GetWidth()*0.4) + self:x(ratewidth) + end + } + + t[#t+1] = LoadFont("Common Bold")..{ + Name = "Grade", + InitCommand = function(self) + self:xy(40,5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:halign(0) + end, + SetCommand = function(self) + local grade = scoreList[scoreIndex]:GetWifeGrade() + self:settext(THEME:GetString("Grade",ToEnumShortString(grade))) + self:diffuse(getGradeColor(grade)) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name = "PercentScore", + InitCommand = function(self) + self:xy(40,5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(0) + end, + SetCommand = function(self) + local score = scoreList[scoreIndex]:GetWifeScore() + score = math.floor(score*1000000)/10000 + local w1 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W1") + local w2 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W2") + local w3 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W3") + local w4 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W4") + local w5 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W5") + local miss = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_Miss") + if score >= 99.5 then + self:settextf("%0.4f%% - %d / %d / %d / %d / %d / %d",score, w1, w2, w3, w4, w5, miss) + else + self:settextf("%0.2f%% - %d / %d / %d / %d / %d / %d",score, w1, w2, w3, w4, w5, miss) + end + self:x(self:GetParent():GetChild("Grade"):GetX()+(self:GetParent():GetChild("Grade"):GetWidth()*0.4)+5) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name = "ReplayAvailability", + InitCommand = function(self) + self:xy(scoreItemWidth-5,5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(1) + end, + SetCommand = function(self) + if scoreList[scoreIndex]:HasReplayData() then + self:settext("Replay Data Available.") + self:diffuse(getMainColor("enabled")) + else + self:settext("Replay Data Unavailable.") + self:diffuse(getMainColor("disabled")) + end + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + Name = "Date", + InitCommand = function(self) + self:xy(scoreItemWidth-5,-5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(1) + end, + SetCommand = function(self) + self:settext(scoreList[scoreIndex]:GetDate()) + end + } + + return t + end + + local function scoreDetail() + local scoreIndex + local t = Def.ActorFrame{ + InitCommand = function(self) + self:diffusealpha(0) + self:xy(scoreItemX, scoreItemY+scoreItemYSpacing+scoreItemHeight/2) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + scoreIndex = params.scoreIndex + inDetail = true + self:finishtweening() + self:xy(scoreItemX, (params.index+1)*(scoreItemHeight+scoreItemYSpacing)+100+scoreItemHeight/2) + self:easeOut(0.5) + self:xy(scoreItemX, scoreItemY+scoreItemYSpacing+scoreItemHeight/2) + self:diffusealpha(1) + end, + HideOnlineScoreDetailMessageCommand = function(self) + inDetail = false + self:playcommand("Hide") + end, + UpdateCLBListMessageCommand = function(self) + inDetail = false + self:playcommand("Hide") + end + } + + -- Watch online replay button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + if scoreList[params.scoreIndex]:HasReplayData() then + self:diffusealpha(0.8) + else + self:diffusealpha(0.2) + end + end, + + TopPressedCommand = function(self) + if scoreList[scoreIndex]:HasReplayData() and inDetail then + self:finishtweening() + self:diffusealpha(1) + self:smooth(0.3) + self:diffusealpha(0.8) + MESSAGEMAN:Broadcast("TriggerExitFromMI", {score = scoreList[scoreIndex]}) + SCREENMAN:GetTopScreen():Cancel() + end + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:diffusealpha(0.4) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("Watch") + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + if scoreList[params.scoreIndex]:HasReplayData() then + self:diffusealpha(1) + else + self:diffusealpha(0.4) + end + end, + } + + -- View Online Profile Button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3 + 95,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.8) + end, + + TopPressedCommand = function(self) + if not inDetail then + return + end + self:finishtweening() + self:diffusealpha(1) + self:smooth(0.3) + self:diffusealpha(0.8) + local urlstring = "https://etternaonline.com/user/" .. scoreList[scoreIndex]:GetDisplayName() + GAMESTATE:ApplyGameCommand("urlnoexit," .. urlstring) + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3 + 95,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("View Profile") + end + } + + -- View Score On EtternaOnline Button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3 + 95 + 95,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.8) + end, + + TopPressedCommand = function(self) + if not inDetail then + return + end + self:finishtweening() + self:diffusealpha(1) + self:smooth(0.3) + self:diffusealpha(0.8) + local urlstring = "https://etternaonline.com/score/view/" .. scoreList[scoreIndex]:GetScoreid() .. scoreList[scoreIndex]:GetUserid() + GAMESTATE:ApplyGameCommand("urlnoexit," .. urlstring) + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3 + 95 + 95,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("View Online") + end + } + + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:diffusealpha(0.2) + self:halign(0):valign(0) + self:zoomto(scoreItemWidth, frameHeight-80) + end, + } + + t[#t+1] = LoadActor(THEME:GetPathG("","OffsetGraph"))..{ + InitCommand = function(self, params) + self:xy(5, 55) + end, + OnCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(offsetInput) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + cheatIndex = params.scoreIndex + if scoreList[params.scoreIndex]:HasReplayData() then + DLMAN:RequestOnlineScoreReplayData( + scoreList[params.scoreIndex], + function() + MESSAGEMAN:Broadcast("DelayedShowOffset") + --self:playcommand("DelayedShowOffset") + end + ) + else + self:RunCommandsOnChildren(function(self) self:playcommand("Update", {width = scoreItemWidth-10, height = frameHeight-140,}) end) + end + end, + DelayedShowOffsetMessageCommand = function(self) + self:RunCommandsOnChildren(function(self) + local params = {width = scoreItemWidth-10, + height = frameHeight-140, + song = song, + steps = steps, + nrv = scoreList[cheatIndex]:GetNoteRowVector(), + dvt = scoreList[cheatIndex]:GetOffsetVector(), + ctt = scoreList[cheatIndex]:GetTrackVector(), + ntt = scoreList[cheatIndex]:GetTapNoteTypeVector(), + columns = steps:GetNumColumns()} + self:playcommand("Update", params) end + ) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(scoreItemWidth/2, (frameHeight-100)/2) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.6) + self:settext("No replay data\n(゜´Д`゜)") + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + if not scoreList[params.scoreIndex]:HasReplayData() then + self:settext("No replay data\n(゜´Д`゜)") + self:visible(true) + end + end, + DelayedShowOffsetMessageCommand = function(self) + if scoreList[cheatIndex]:HasReplayData() and scoreList[cheatIndex]:GetNoteRowVector() == nil then + self:settext("Missing Noterows from Online Replay\n(゜´Д`゜)") + else + self:settext("No replay data\n(゜´Д`゜)") + end + self:visible(not scoreList[cheatIndex]:HasReplayData() or scoreList[cheatIndex]:GetNoteRowVector() == nil) + end + } + + return t + + end + + for i=1, maxItems do + t[#t+1] = scoreListItem(i) + end + + t[#t+1] = scoreDetail() + + return t + +end + +local t = Def.ActorFrame { + OnCommand = function(self) + top = SCREENMAN:GetTopScreen() + MESSAGEMAN:Broadcast("SetStepsType",{st = stepsType}) + MESSAGEMAN:Broadcast("SetSteps",{steps = steps}) + scoreList = DLMAN:GetChartLeaderBoard(steps:GetChartKey(), currentCountry) + if #scoreList == 0 then + updateLeaderBoardForCurrentChart() + end + top:AddInputCallback(input) + end +} + +t[#t+1] = LoadActor("../_mouse") + +t[#t+1] = LoadActor("../_frame") + +t[#t+1] = topRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(0) + end +} + +t[#t+1] = stepsListRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(1) + end +} + +t[#t+1] = stepsBPMRow() .. { + InitCommand = function(self) + self:xy(160, 58) + self:delayedFadeIn(2) + end +} + +-- The main, central container (Online Leaderboard) +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X / 2, 110) + end, + + Def.Quad { + InitCommand = function (self) + self:zoomto(frameWidth,frameHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() then + movePage(1) + end + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Online Scores") + end + }, + LoadFont("Common Normal") .. { + Name = "RequestStatus", + InitCommand = function(self) + self:xy(5,30) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("") + end, + UpdateCLBListMessageCommand = function(self) + if #scoreList == 0 then + self:settext("Online scores not tracked or no scores recorded...") + else + self:settext("") + end + end + } + +} + +-- Current Rate/All Rates Toggle Button +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(10,155) + end, + + Def.Quad { + InitCommand = function(self) + self:diffuse(color("#000000")) + self:xy(0,0) + self:halign(0) + self:diffusealpha(0.8) + self:zoomto(150,25) + end + }, + + quadButton(6) .. { + Name = "ToggleRateFilter", + InitCommand = function(self) + self:diffuse(color("#FFFFFF")) + self:xy(0, 0) + self:halign(0) + self:diffusealpha(0) + self:zoomto(150, 25) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.0) + MESSAGEMAN:Broadcast("ToggleRateFilter") + updateLeaderBoardForCurrentChart() + end + }, + + LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(75, 0) + --self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:playcommand("Set") + end, + SetCommand = function(self) + if DLMAN:GetCurrentRateFilter() then + self:settext(filts[2]) + else + self:settext(filts[1]) + end + end, + ToggleRateFilterMessageCommand = function(self) + DLMAN:ToggleRateFilter() + self:playcommand("Set") + end + } +} + + +-- Top Scores/All Scores Toggle Button +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(10,185) + end, + + Def.Quad { + InitCommand = function(self) + self:diffuse(color("#000000")) + self:xy(0,0) + self:halign(0) + self:diffusealpha(0.8) + self:zoomto(150,25) + end + }, + + quadButton(6) .. { + Name = "TopScoreToggle", + InitCommand = function(self) + self:diffuse(color("#FFFFFF")) + self:xy(0, 0) + self:halign(0) + self:diffusealpha(0) + self:zoomto(150, 25) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.0) + MESSAGEMAN:Broadcast("TopScoreToggle") + updateLeaderBoardForCurrentChart() + end + }, + + LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(75, 0) + --self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:playcommand("Set") + end, + SetCommand = function(self) + if DLMAN:GetTopScoresOnlyFilter() then + self:settext(topfilts[1]) + else + self:settext(topfilts[2]) + end + end, + TopScoreToggleMessageCommand = function(self) + DLMAN:ToggleTopScoresOnlyFilter() + self:playcommand("Set") + end + } +} + + +t[#t+1] = scoreList() .. { + Name = "ScoreList", + InitCommand = function(self) + self:xy(SCREEN_CENTER_X / 2, 110) + self:delayedFadeIn(5) + lbActor = self + end +} + + +t[#t+1] = LoadActor("../_cursor") + +return t diff --git a/BGAnimations/ScreenChartLeaderboard underlay/default.lua b/BGAnimations/ScreenChartLeaderboard underlay/default.lua new file mode 100644 index 00000000..976d688a --- /dev/null +++ b/BGAnimations/ScreenChartLeaderboard underlay/default.lua @@ -0,0 +1,10 @@ +local t = Def.ActorFrame{} + +t[#t+1] = Def.Quad { + InitCommand = function(self) + self:diffusealpha(0.9) + self:FullScreen() + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenChartPreview decorations/default.lua b/BGAnimations/ScreenChartPreview decorations/default.lua new file mode 100644 index 00000000..a8235dec --- /dev/null +++ b/BGAnimations/ScreenChartPreview decorations/default.lua @@ -0,0 +1,3 @@ +local t = Def.ActorFrame{} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenGroupInfo in.lua b/BGAnimations/ScreenChartPreview out.lua similarity index 100% rename from BGAnimations/ScreenGroupInfo in.lua rename to BGAnimations/ScreenChartPreview out.lua diff --git a/BGAnimations/ScreenChartPreview overlay/default.lua b/BGAnimations/ScreenChartPreview overlay/default.lua new file mode 100644 index 00000000..9bdcb2d0 --- /dev/null +++ b/BGAnimations/ScreenChartPreview overlay/default.lua @@ -0,0 +1,785 @@ +local pn = GAMESTATE:GetEnabledPlayers()[1] +local song = GAMESTATE:GetCurrentSong() +local steps = GAMESTATE:GetCurrentSteps(pn) +local stepsType = steps:GetStepsType() +local usingreverse = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingReverse() + +local ssm +local NF +local NFParent +local musicratio = 1 + +local validStepsType = { + 'StepsType_Dance_Single', + 'StepsType_Dance_Solo', + 'StepsType_Dance_Double', +} +local maxNumDifficulties = 0 +for _,st in pairs(validStepsType) do + maxNumDifficulties = math.max(maxNumDifficulties, #song:GetStepsByStepsType(st)) +end + +local function getNextStepsType(n) + for i = 1, #validStepsType do + if validStepsType[i] == stepsType then + stepsType = validStepsType[(i+n-1+#validStepsType)%#validStepsType+1] -- 1 index scks + return stepsType + end + end +end + +local function meterComparator(stepA, stepB) + local diffA = stepA:GetDifficulty() + local diffB = stepB:GetDifficulty() + + return Enum.Reverse(Difficulty)[diffA] < Enum.Reverse(Difficulty)[diffB] +end + +local stepsTable = {} + +-- I can't believe I have to do this +local function findCurStepIndex(givenSteps) + for i = 1, #stepsTable do + if stepsTable[i]:GetChartKey() == givenSteps:GetChartKey() then + return i + end + end +end + +local curStepIndex = 0 + +local function input(event) + + if event.type == "InputEventType_FirstPress" then + if event.button == "Back" or event.button == "Start" then + SCREENMAN:GetTopScreen():Cancel() + ssm:DeletePreviewNoteField(NFParent) + MESSAGEMAN:Broadcast("PreviewNoteFieldDeleted") + end + + if event.button == "EffectUp" then + changeMusicRate(0.05) + end + + if event.button == "EffectDown" then + changeMusicRate(-0.05) + end + + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + end + + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + end + + if event.DeviceInput.button == "DeviceButton_right mouse button" then + ssm:PausePreviewNoteField() + end + + end + return false + +end + +local top +local frameWidth = 430 +local frameHeight = 340 + +local verticalSpacing = 7 +local horizontalSpacing = 10 + +local function topRow() + local frameWidth = SCREEN_WIDTH - 20 + local frameHeight = 40 + + local t = Def.ActorFrame{ + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + end + } + + t[#t+1] = Def.Sprite { + Name = "Banner", + InitCommand = function(self) + self:x(-frameWidth/2 + 5) + self:halign(0) + local bnpath = song:GetBannerPath() + if not bnpath then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) + self:scaletoclipped(96, 30) + end + } + + t[#t+1] = LoadFont("Common BLarge") .. { + Name = "SongTitle", + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, -9) + self:zoom(0.25) + self:halign(0) + self:settext(song:GetMainTitle()) + if #song:GetDisplaySubTitle() == 0 then + self:zoom(0.35):y(-5) + end + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + local actor = self:GetParent():GetChild("SongTitle") + local x = actor:GetX() + actor:GetWidth()*actor:GetZoomX() + 2 + local y = actor:GetY() - 2 + + self:xy(x,y) + self:zoom(0.3) + self:halign(0) + self:playcommand("Set") + end, + SetCommand = function(self) + local length = song:GetStepsSeconds()/getCurRateValue() + self:settextf("%s",SecondsToMSS(length)) + self:diffuse(getSongLengthColor(length)) + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 1) + self:zoom(0.35) + self:halign(0) + self:settext(song:GetDisplaySubTitle()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 9) + self:zoom(0.35) + self:halign(0) + self:settext("// "..song:GetDisplayArtist()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,-1) + self:zoom(0.5) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local diff = curSteps:GetDifficulty() + local stype = curSteps:GetStepsType() + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + meter = curSteps:GetMeter() + end + + local difftext + if diff == 'Difficulty_Edit' then + difftext = curSteps:GetDescription() + difftext = difftext == '' and getDifficulty(diff) or difftext + else + difftext = getDifficulty(diff) + end + + self:settext(ToEnumShortString(stype):gsub("%_"," ").." "..difftext.." "..meter) + self:diffuse(getDifficultyColor(GetCustomDifficulty(stype,diff))) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,9) + self:zoom(0.35) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local notes = 0 + if curSteps ~= nil then + notes = curSteps:GetRadarValues(pn):GetValue("RadarCategory_Notes") + end + self:settextf("%d Notes", notes) + self:diffuse(Saturation(getDifficultyColor(GetCustomDifficulty(curSteps:GetStepsType(),curSteps:GetDifficulty())),0.3)) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name="MSDAvailability", + InitCommand = function(self) + self:xy(frameWidth/2-5,-11) + self:zoom(0.30) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + if curSteps ~= nil then + curStepIndex = findCurStepIndex(curSteps) + + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + self:settext("Default") + self:diffuse(color(colorConfig:get_data().main.disabled)) + else + self:settext("MSD") + self:diffuse(color(colorConfig:get_data().main.enabled)) + end + end + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "round_star")) .. { + InitCommand = function(self) + self:xy(-frameWidth/2+1,-frameHeight/2+1) + self:zoom(0.3) + self:wag() + self:diffuse(Color.Yellow) + + if not song:IsFavorited() then + self:visible(false) + end + end + } + + return t +end + +local function stepsListRow() + local frameWidth = 150 + local frameHeight = 25 + local topRowFrameWidth = SCREEN_WIDTH - 20 + local topRowFrameHeight = 40 + + local t = Def.ActorFrame{ + SetStepsTypeMessageCommand = function(self, params) + stepsTable = song:GetStepsByStepsType(params.st) + table.sort(stepsTable, meterComparator) + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:xy(-topRowFrameWidth/2, topRowFrameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(0) + end + } + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:zoom(0.4) + self:xy(-topRowFrameWidth/2+frameWidth/2,topRowFrameHeight) + end, + SetCommand = function(self) + self:settext(ToEnumShortString(stepsType):gsub("%_"," ")) + end + } + + for i = 1, maxNumDifficulties do + + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(40, frameHeight) + self:y(topRowFrameHeight) + self:diffuse(color("#000000")):diffusealpha(0) + self:halign(0) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) + end, + SetCommand = function(self) + local curSteps = stepsTable[i] + if curSteps then + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowCommand = function(self) + self:y(topRowFrameHeight) + self:finishtweening() + self:sleep((i-1)*0.03) + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)) + self:diffusealpha(0.8) + end, + HideCommand = function(self) + self:diffusealpha(0) + self:y(SCREEN_HEIGHT*10) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) + end, + TopPressedCommand = function(self) + local dir = i - curStepIndex + if dir ~= 0 then + ssm:ChangeSteps(dir) + MESSAGEMAN:Broadcast("SetSteps", {steps = stepsTable[i]}) + end + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + local stype = steps:GetStepsType() + self:zoom(0.4) + self:diffusealpha(0) + self:xy((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10, topRowFrameHeight) + self:settext("0") + end, + SetCommand = function(self) + local curSteps = stepsTable[i] + if curSteps then + + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + meter = curSteps:GetMeter() + end + + self:settext(meter) + self:diffuse(color(colorConfig:get_data().difficulty[curSteps:GetDifficulty()])) + self:diffusealpha(0) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowCommand = function(self) + self:finishtweening() + self:sleep((i-1)*0.05) + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:finishtweening() + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10) + self:diffusealpha(0) + end + } + end + + return t +end + +local function stepsBPMRow() + local topRowFrameWidth = 0 + local topRowFrameHeight = 40 + local frameWidth = 150 + local frameHeight = 25 + local t = Def.ActorFrame{} + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, 25) + self:xy(topRowFrameWidth, topRowFrameHeight + frameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(1) + end + } + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(topRowFrameWidth/2-frameWidth/2, topRowFrameHeight + frameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:faderight(0.5) + end, + TopPressedCommand = function(self, params) + changeMusicRate(-0.05) + self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(topRowFrameWidth/2, topRowFrameHeight + frameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:fadeleft(0.5) + end, + TopPressedCommand = function(self, params) + changeMusicRate(0.05) + self:GetParent():GetChild("TriangleRight"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleLeft", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(topRowFrameWidth/2-frameWidth+10,topRowFrameHeight + frameHeight) + self:rotationz(-90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleRight", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(topRowFrameWidth/2-10,topRowFrameHeight + frameHeight) + self:rotationz(90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:zoom(0.35) + self:xy(topRowFrameWidth/2-75,topRowFrameHeight-4 + frameHeight) + end, + SetStepsMessageCommand = function(self, params) + if params.steps then + local bpms = steps:GetTimingData():GetActualBPM() + if bpms[1] == bpms[2] and bpms[1]~= nil then + self:settext(string.format("BPM: %d",bpms[1]*getCurRateValue())) + else + self:settext(string.format("BPM: %d-%d (%d)",bpms[1]*getCurRateValue(),bpms[2]*getCurRateValue(),getCommonBPM(song:GetTimingData():GetBPMsAndTimes(true),song:GetLastBeat()))) + end + end + end + } + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:zoom(0.3) + self:xy(topRowFrameWidth/2-75,topRowFrameHeight+4 + frameHeight) + end, + SetStepsMessageCommand = function(self, params) + self:settext(getCurRateDisplayString()) + end + } + + return t +end + +local t = Def.ActorFrame { + OnCommand = function(self) + top = SCREENMAN:GetTopScreen() + MESSAGEMAN:Broadcast("SetStepsType",{st = stepsType}) + MESSAGEMAN:Broadcast("SetSteps",{steps = steps}) + top:AddInputCallback(input) + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end, + ExitScreenMessageCommand = function(self) + ssm:DeletePreviewNoteField(NFParent) + MESSAGEMAN:Broadcast("PreviewNoteFieldDeleted") + end +} + +t[#t+1] = LoadActor("../_mouse") + +t[#t+1] = LoadActor("../_frame") .. { + InitCommand = function(self) + self:draworder(101) + end +} + +t[#t+1] = topRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(0) + self:draworder(100000) + end +} + +t[#t+1] = stepsListRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(1) + end +} + +t[#t+1] = stepsBPMRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X + frameWidth - 13, 25) + self:delayedFadeIn(2) + end +} + +t[#t+1] = LoadActor("../ScreenMusicInfo overlay/stepsinfo") .. { + InitCommand = function(self) + self:xy(capWideScale(135,160),140) + self:delayedFadeIn(3) + end +} + +t[#t+1] = LoadActor("../ScreenMusicInfo overlay/ssrbreakdown") .. { + InitCommand = function(self) + self:xy(capWideScale(135,160),315) + self:delayedFadeIn(4) + end +} + +local function getColorForDensity(density, nColumns) + -- Generically (generally? intelligently? i dont know) set a range + -- Colors are color(0.1,0.1,0.1) to color(0.7,0.7,0.7) + -- The value var describes the level of density. + -- Beginning at 0.1 for 0, to 0.7 for nColumns. + -- You wouldn't give nColumns = 1 to this function or else something is wrong with you. + local value = 0.1 + (nColumns - (density - 1)) * (0.6 / (nColumns - 1)) + return color(tostring(value)..","..tostring(value)..","..tostring(value)) +end + +local function makeABar(vertices, x, y, barWidth, barHeight, thecolor) + -- These bars are horizontal, progressively going down the screen + -- Their corners are: (x,y), (x+barHeight,y), (x,y+barWidth), (x+barHeight, y+barWidth) + vertices[#vertices + 1] = {{x,y-barWidth,0},thecolor} + vertices[#vertices + 1] = {{x+barHeight,y-barWidth,0},thecolor} + vertices[#vertices + 1] = {{x+barHeight,y,0},thecolor} + vertices[#vertices + 1] = {{x,y,0},getMiscColor("ChordGraphGradientDark")} +end + +local function seekOrHighlight(self) + local pos = ssm:GetPreviewNoteFieldMusicPosition() / musicratio + self:GetChild("PreviewProgress"):zoomto(84, math.min(pos, frameHeight-20)) + self:queuecommand("Highlight") +end + +-- The container for the density graph and scrollbar +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X / 1.2 - 36 + frameWidth + horizontalSpacing, 110) + self:GetChild("ChordDensityGraph"):queuecommand("GraphUpdate") + self:SetUpdateFunction(seekOrHighlight) + self:queuecommand("DelayedUpdateHack") + end, + DelayedUpdateHackCommand = function(self) + -- i dunno maybe the song might not be ready in time, just in case bro + musicratio = GAMESTATE:GetCurrentSong():GetLastSecond() / (frameHeight - 20) + end, + + + -- container bg + Def.Quad { + InitCommand = function (self) + self:zoomto(84,frameHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end + }, + + Def.Quad { + Name = "PreviewProgress", + InitCommand = function(self) + self:xy(84/2, 20) + self:zoomto(84, 200) + self:diffuse(getMiscColor("PreviewProgress")) + self:diffusealpha(0.5) + self:valign(0) + end + }, + + Def.ActorMultiVertex { + Name = "ChordDensityGraph", + SetStepsMessageCommand = function(self, params) + if params.steps then + self:queuecommand("GraphUpdate") + end + end, + CurrentRateChangedMessageCommand = function(self) + if steps then + self:queuecommand("GraphUpdate") + end + end, + GraphUpdateCommand = function(self) + steps = GAMESTATE:GetCurrentSteps(PLAYER_1) + if steps then + local nColumns = steps:GetNumColumns() + local rate = math.max(1, getCurRateValue()) + local graphVectors = steps:GetCDGraphVectors(rate) + if graphVectors == nil then + self:SetVertices({}) + self:SetDrawState( {Mode = "DrawMode_Quads", First = 0, Num = 0} ) + return + end + local npsVector = graphVectors[1] -- CPS Vector 1 (Taps per second) + local numberOfRows = #npsVector + local rowWidth = (frameHeight - 20) / numberOfRows * rate + + -- Width scale of graph relative to max nps + local mWidth = 0 + for i = 1, #npsVector do + if npsVector[i] * 2 > mWidth then + mWidth = npsVector[i] * 2 + end + end + + self:GetParent():GetChild("NPSText"):settext(mWidth / 2 .. " max NPS") + mWidth = 84 / mWidth + local verts = {} + for density = 1, nColumns do + for row = 1, numberOfRows do + if graphVectors[density][row] > 0 then + local barColor = getColorForDensity(density, nColumns) + makeABar(verts, 0, 20+math.min(row * rowWidth, frameHeight-20), rowWidth, graphVectors[density][row] * 2 * mWidth, barColor) + end + end + end + + self:SetVertices(verts) + self:SetDrawState( {Mode = "DrawMode_Quads", First = 1, Num = #verts} ) + + end + end + }, + + LoadFont("Common Bold") .. { + Name = "NPSText", + InitCommand = function(self) + self:xy(84/2,10) + self:zoom(0.4) + --self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("") + self:maxwidth(84 * 2.2) + end + }, + + -- This handles the seeking through the preview + Def.Quad { + Name = "PreviewClickable", + InitCommand = function(self) + self:diffuse(color("#000000")) + self:y(20) + self:zoomto(84,frameHeight-20) + self:halign(0):valign(0) + self:diffusealpha(0) + end, + HighlightCommand = function(self) + if isOver(self) then + self:GetParent():GetChild("PreviewSeek"):visible(true) + self:GetParent():GetChild("PreviewSeek"):y(INPUTFILTER:GetMouseY() - self:GetParent():GetY()) + else + self:GetParent():GetChild("PreviewSeek"):visible(false) + end + end, + MouseLeftClickMessageCommand = function(self) + if isOver(self) then + ssm:SetPreviewNoteFieldMusicPosition( (INPUTFILTER:GetMouseY() - self:GetParent():GetY() - 20) * musicratio) + end + end, + WheelUpSlowMessageCommand = function(self) + if isOver(self) then + ssm:SetPreviewNoteFieldMusicPosition( ssm:GetPreviewNoteFieldMusicPosition() - 0.1 ) + end + end, + WheelDownSlowMessageCommand = function(self) + if isOver(self) then + ssm:SetPreviewNoteFieldMusicPosition( ssm:GetPreviewNoteFieldMusicPosition() + 0.1 ) + end + end + }, + + -- This is the position bar for seeking + Def.Quad { + Name = "PreviewSeek", + InitCommand = function(self) + self:y(20) + self:zoomto(84, 1) + self:diffuse(getMiscColor("PreviewSeek")) + self:halign(0) + end + } + +} + +-- The main, central container (Preview Notefield) +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X / 1.2 - 36, 110) + end, + + Def.Quad { + InitCommand = function (self) + self:zoomto(frameWidth,frameHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("") + end + }, + -- The Preview Notefield. + Def.ActorFrame { + InitCommand = function(self) + NFParent = self + ssm = GHETTOGAMESTATE:getSSM() + self:queuecommand("StartPreview") + end, + + StartPreviewCommand = function(self) + NF = ssm:CreatePreviewNoteField() + if NF == nil then + return + end + NF:zoom(0.5):draworder(100) + ssm:dootforkfive(NFParent) + NF:xy(frameWidth / 2, 50) + if usingreverse then + NF:y(50 * 1.5 + 215) + end + NFParent:SortByDrawOrder() + end + } +} + + +t[#t+1] = LoadActor("../_cursor") + +return t diff --git a/BGAnimations/ScreenChartPreview underlay/default.lua b/BGAnimations/ScreenChartPreview underlay/default.lua new file mode 100644 index 00000000..976d688a --- /dev/null +++ b/BGAnimations/ScreenChartPreview underlay/default.lua @@ -0,0 +1,10 @@ +local t = Def.ActorFrame{} + +t[#t+1] = Def.Quad { + InitCommand = function(self) + self:diffusealpha(0.9) + self:FullScreen() + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenChatOverlay overlay.lua b/BGAnimations/ScreenChatOverlay overlay.lua new file mode 100644 index 00000000..6a4a6f66 --- /dev/null +++ b/BGAnimations/ScreenChatOverlay overlay.lua @@ -0,0 +1,663 @@ +local lastx, lasty = 0, 0 +local width, height = SCREEN_WIDTH, SCREEN_HEIGHT * 0.035 +local maxlines = 5 +local lineNumber = 5 +local inputLineNumber = 2 +local tabHeight = 1 +local maxTabs = 10 +local x, y = 0, SCREEN_HEIGHT - height * (lineNumber + inputLineNumber + tabHeight) +local moveY = 0 +local mousex, mousey = -1, -1 +local scale = 0.4 +local minimised = false +local typing = false +local typingText = "" +local transparency = 0.667 +local curmsgh = 0 +local closeTabSize = 10 +local Colors = { + background = color("#333333"), + input = color("#888888"), + activeInput = color("#9977BB"), + output = color("#545454"), + bar = color("#666666"), + tab = color("#555555"), + activeTab = color("#999999") +} +local chats = {} +chats[0] = {} +chats[1] = {} +chats[2] = {} +chats[0][""] = {} +local tabs = {{0, ""}} +--chats[tabName][tabType] +--tabtype: 0=lobby, 1=room, 2=pm +local messages = chats[0][""] +local currentTabName = "" +local currentTabType = 0 + +function changeTab(tabName, tabType) + currentTabName = tabName + currentTabType = tabType + if not chats[tabType][tabName] then + local i = 1 + local done = false + while not done do + if not tabs[i] then + tabs[i] = {tabType, tabName} + done = true + end + end + chats[tabType][tabName] = {} + end + messages = chats[tabType][tabName] +end +local chat = Def.ActorFrame {} +local currentScreen +local show = true +local online = IsNetSMOnline() and IsSMOnlineLoggedIn(PLAYER_1) and NSMAN:IsETTP() + +chat.MinimiseMessageCommand = function(self) + self:linear(0.25) + moveY = minimised and height * (lineNumber + inputLineNumber + tabHeight - 1) or 0 + self:y(moveY) +end +local i = 0 +chat.InitCommand = function(self) + online = IsNetSMOnline() and IsSMOnlineLoggedIn(PLAYER_1) and NSMAN:IsETTP() + self:visible(false) +end +local isGameplay +local isInSinglePlayer +chat.ScreenChangedMessageCommand = function(self) + local s = SCREENMAN:GetTopScreen() + if not s then + return + end + local oldScreen = currentScreen + currentScreen = s:GetName() + + -- prevent the chat from showing in singleplayer because it can be annoying + if + oldScreen ~= currentScreen and + (currentScreen == "ScreenSelectMusic" or currentScreen == "ScreenTitleMenu" or + currentScreen == "ScreenOptionsService") + then + isInSinglePlayer = true + end + if string.sub(currentScreen, 1, 9) == "ScreenNet" and currentScreen ~= "ScreenNetSelectProfile" then + isInSinglePlayer = false + end + + online = IsNetSMOnline() and IsSMOnlineLoggedIn(PLAYER_1) and NSMAN:IsETTP() + isGameplay = (currentScreen == "ScreenGameplay" or currentScreen == "ScreenNetGameplay") + + if isGameplay or isInSinglePlayer then + self:visible(false) + show = false + typing = false + s:setInterval( + function() + self:visible(false) + end, + 0.025 + ) + else + self:visible(online and not isInSinglePlayer) + show = true + end + if currentScreen == "ScreenNetSelectMusic" then + for i = 1, #tabs do + if tabs[i] and tabs[i][2] == NSMAN:GetCurrentRoomName() then + changeTab(tabs[i][2], tabs[i][1]) + end + end + end + MESSAGEMAN:Broadcast("UpdateChatOverlay") +end +chat.MultiplayerDisconnectionMessageCommand = function(self) + online = false + self:visible(false) + typing = false + MESSAGEMAN:Broadcast("UpdateChatOverlay") + chats = {} + chats[0] = {} + chats[1] = {} + chats[2] = {} + chats[0][""] = {} + tabs = {{0, ""}} + changeTab("", 0) + SCREENMAN:set_input_redirected("PlayerNumber_P1", false) +end + +local bg +chat[#chat + 1] = + Def.Quad { + Name = "Background", + InitCommand = function(self) + bg = self + self:diffuse(Colors.background) + self:diffusealpha(transparency) + self:stretchto(x, y, width + x, height * (lineNumber + inputLineNumber + tabHeight) + y) + end +} +local minbar +chat[#chat + 1] = + Def.Quad { + Name = "Bar", + InitCommand = function(self) + minbar = self + self:diffuse(Colors.bar) + self:diffusealpha(transparency) + self:stretchto(x, y, width + x, height + y) + end, + ChatMessageCommand = function(self) + if minimised then + self:linear(0.25) + self:diffuse(Colors.activeInput) + end + end, + MinimiseMessageCommand = function(self) + if not minimised then + self:diffuse(Colors.bar) + end + end +} +chat[#chat + 1] = + LoadFont("Common Normal") .. + { + Name = "BarLabel", + InitCommand = function(self) + self:settext("CHAT") + self:halign(0):valign(0.5) + self:zoom(0.5) + self:diffuse(color("#000000")) + self:visible(true) + self:xy(x + 4, y + height * 0.5) + end + } +chat[#chat + 1] = + LoadFont("Common Normal") .. + { + Name = "BarMinimiseButton", + InitCommand = function(self) + self:settext("-") + self:halign(1):valign(0.5) + self:zoom(0.8) + self:diffuse(color("#000000")) + self:visible(true) + self:xy(x + width - 4, y + 5) + end, + MinimiseMessageCommand = function(self) + self:settext(minimised and "+" or "-") + end + } + +local chatWindow = + Def.ActorFrame { + InitCommand = function(self) + self:visible(true) + end, + ChatMessageCommand = function(self, params) + local msgs = chats[params.type][params.tab] + local newTab = false + if not msgs then + chats[params.type][params.tab] = {} + msgs = chats[params.type][params.tab] + tabs[#tabs + 1] = {params.type, params.tab} + newTab = true + end + msgs[#msgs + 1] = os.date("%X") .. params.msg + if msgs == messages or newTab then --if its the current tab + MESSAGEMAN:Broadcast("UpdateChatOverlay") + end + end +} +local chatbg +chatWindow[#chatWindow + 1] = + Def.Quad { + Name = "ChatWindow", + InitCommand = function(self) + chatbg = self + self:diffuse(Colors.output) + self:diffusealpha(transparency) + end, + UpdateChatOverlayMessageCommand = function(self) + self:stretchto(x, height * (1 + tabHeight) + y, width + x, height * (maxlines + tabHeight) + y) + curmsgh = 0 + MESSAGEMAN:Broadcast("UpdateChatOverlayMsgs") + end +} +chatWindow[#chatWindow + 1] = + LoadColorFont("Common Normal") .. + { + Name = "ChatText", + InitCommand = function(self) + self:settext("") + self:halign(0):valign(1) + self:vertspacing(0) + self:zoom(scale) + self:SetMaxLines(lineNumber, 1) + self:wrapwidthpixels((width - 8) / scale) + self:xy(x + 4, y + height * (lineNumber + tabHeight) - 4) + end, + UpdateChatOverlayMsgsMessageCommand = function(self) + local t = "" + for i = lineNumber - 1, lineNumber - maxlines, -1 do + if messages[#messages - i] then + t = t .. messages[#messages - i] .. "\n" + end + end + self:settext(t) + end + } + +local tabWidth = width / maxTabs +for i = 0, maxTabs - 1 do + chatWindow[#chatWindow + 1] = + Def.ActorFrame { + Name = "Tab" .. i + 1, + UpdateChatOverlayMessageCommand = function(self) + self:visible(not (not tabs[i + 1])) + end, + Def.Quad { + InitCommand = function(self) + self:diffuse(Colors.tab) + self:diffusealpha(transparency) + end, + UpdateChatOverlayMessageCommand = function(self) + self:diffuse( + (tabs[i + 1] and currentTabName == tabs[i + 1][2] and currentTabType == tabs[i + 1][1]) and Colors.activeTab or + Colors.tab + ) + self:stretchto(x + tabWidth * i, y + height, x + tabWidth * (i + 1), y + height * (1 + tabHeight)) + end + }, + LoadFont("Common Normal") .. + { + InitCommand = function(self) + self:halign(0):valign(0) + self:maxwidth(tabWidth * 2) + self:zoom(scale) + self:diffuse(color("#000000")) + self:xy(x + tabWidth * i + 4, y + height * (1 + (tabHeight / 4))) + end, + UpdateChatOverlayMessageCommand = function(self) + if not tabs[i + 1] then + self:settext("") + return + end + if tabs[i + 1][1] == 0 and tabs[i + 1][2] == "" then + self:settext("Lobby") + else + self:settext(tabs[i + 1][2] or "") + end + end + }, + LoadFont("Common Normal") .. + { + InitCommand = function(self) + self:halign(0):valign(0) + self:maxwidth(tabWidth) + self:zoom(scale) + self:diffuse(color("#000000")) + self:xy(x + tabWidth * (i + 1) - closeTabSize, y + height * (1 + (tabHeight / 4))) + end, + UpdateChatOverlayMessageCommand = function(self) + if + tabs[i + 1] and + ((tabs[i + 1][1] == 0 and tabs[i + 1][2] == "") or + (tabs[i + 1][1] == 1 and tabs[i + 1][2] ~= nil and tabs[i + 1][2] == NSMAN:GetCurrentRoomName())) + then + self:settext("") + else + self:settext("X") + end + end + } + } +end + +local inbg +chatWindow[#chatWindow + 1] = + Def.Quad { + Name = "ChatBox", + InitCommand = function(self) + inbg = self + self:diffuse(Colors.input) + self:diffusealpha(transparency) + end, + UpdateChatOverlayMessageCommand = function(self) + self:stretchto(x, height * (maxlines + 1) + y + 4, width + x, height * (maxlines + 1 + inputLineNumber) + y) + self:diffuse(typing and Colors.activeInput or Colors.input):diffusealpha(transparency) + end +} +chatWindow[#chatWindow + 1] = + LoadFont("Common Normal") .. + { + Name = "ChatBoxText", + InitCommand = function(self) + self:settext("") + self:halign(0):valign(0) + self:zoom(scale) + self:wrapwidthpixels((width - 8) / scale) + self:diffuse(color("#FFFFFF")) + end, + UpdateChatOverlayMessageCommand = function(self) + self:settext(typingText) + self:wrapwidthpixels((width - 8) / scale) + self:xy(x + 4, height * (lineNumber + 1) + y + 4 + 4) + end + } + +chat[#chat + 1] = chatWindow + +chat.UpdateChatOverlayMessageCommand = function(self) + SCREENMAN:set_input_redirected("PlayerNumber_P1", typing) +end + +function shiftTab(fromIndex, toIndex) + -- tabs[index of tab][parameter table....] + -- [1 is type, 2 is tab contents?] + tabs[toIndex] = tabs[fromIndex] + tabs[fromIndex] = nil +end + +function shiftAllTabs(emptyIndex) + for i = emptyIndex + 1, maxTabs - 1 do + shiftTab(i, i - 1) + end +end + +function overTab(mx, my) + for i = 0, maxTabs - 1 do + if tabs[i + 1] then + if + mx >= x + tabWidth * i and my >= y + height + moveY and mx <= x + tabWidth * (i + 1) and + my <= y + height * (1 + tabHeight) + moveY + then + return i + 1, mx >= x + tabWidth * (i + 1) - closeTabSize + end + end + end + return nil, nil +end + +function MPinput(event) + if (not show or not online) or isGameplay then + return false + end + local update = false + if event.DeviceInput.button == "DeviceButton_left mouse button" then + if typing then + update = true + end + typing = false + local mx, my = INPUTFILTER:GetMouseX(), INPUTFILTER:GetMouseY() + if isOver(minbar) then --hard mouse toggle -mina + minimised = not minimised + MESSAGEMAN:Broadcast("Minimise") + update = true + elseif isOver(inbg) and not minimised then + typing = true + update = true + elseif mx >= x and mx <= x + width and my >= y + moveY and my <= y + height + moveY then + mousex, mousey = mx, my -- no clue what this block of code is for + lastx, lasty = x, y + update = true + elseif not minimised then + local tabButton, closeTab = overTab(mx, my) + if not tabButton then + mousex, mousey = -1, -1 + if typing then + update = true + end + else + if event.type == "InputEventType_FirstPress" then -- only change tabs on press (to stop repeatedly closing tabs or changing to a tab we close) -poco + if not closeTab then + changeTab(tabs[tabButton][2], tabs[tabButton][1]) + else + local tabT = tabs[tabButton][1] + local tabN = tabs[tabButton][2] + if (tabT == 0 and tabN == "") or (tabT == 1 and tabN ~= nil and tabN == NSMAN:GetCurrentRoomName()) then + return false + end + tabs[tabButton] = nil + if chats[tabT][tabN] == messages then + for i = #tabs, 1, -1 do + if tabs[i] then + changeTab(tabs[i][2], tabs[i][1]) + end + end + end + chats[tabT][tabN] = nil + shiftAllTabs(tabButton) + end + update = true + end + end + end + end + + -- hard kb toggle + if event.type == "InputEventType_Release" and event.DeviceInput.button == "DeviceButton_insert" then + minimised = not minimised + MESSAGEMAN:Broadcast("Minimise") + update = true + if not minimize then + typingText = "" + end + end + + if not typing and event.type == "InputEventType_Release" then -- keys for auto turning on chat if not already on -mina + if event.DeviceInput.button == "DeviceButton_/" then + typing = true + update = true + if minimised then + minimised = not minimised + MESSAGEMAN:Broadcast("Minimise") + end + typingText = "/" + end + end + + if typing then + if event.type == "InputEventType_Release" then + if event.DeviceInput.button == "DeviceButton_enter" then + if typingText:len() > 0 then + NSMAN:SendChatMsg(typingText, currentTabType, currentTabName) + typingText = "" + elseif typingText == "" then + typing = false -- pressing enter when text is empty to deactive chat is expected behavior -mina + end + update = true + end + elseif event.button == "Back" then + typingText = "" + typing = false + update = true + elseif event.DeviceInput.button == "DeviceButton_space" then + typingText = typingText .. " " + update = true + elseif event.DeviceInput.button == "DeviceButton_delete" then -- reset msg with delete (since there's no cursor) + typingText = "" + update = true + elseif + (INPUTFILTER:IsBeingPressed("left ctrl") or INPUTFILTER:IsBeingPressed("right ctrl")) and + event.DeviceInput.button == "DeviceButton_v" + then + typingText = typingText .. HOOKS:GetClipboard() + update = true + elseif event.DeviceInput.button == "DeviceButton_backspace" then + typingText = typingText:sub(1, -2) + update = true + elseif event.char then + typingText = (tostring(typingText) .. tostring(event.char)):gsub("[^%g%s]", "") + update = true + end + end + + if event.DeviceInput.button == "DeviceButton_mousewheel up" and event.type == "InputEventType_FirstPress" then + if isOver(chatbg) then + if lineNumber < #messages then + lineNumber = lineNumber + 1 + end + update = true + end + end + if event.DeviceInput.button == "DeviceButton_mousewheel down" and event.type == "InputEventType_FirstPress" then + if isOver(chatbg) then + if lineNumber > maxlines then + lineNumber = lineNumber - 1 + end + update = true + end + end + + -- right click over the chat to minimize + if event.DeviceInput.button == "DeviceButton_right mouse button" and isOver(bg) then + if event.type == "InputEventType_FirstPress" then + minimised = not minimised + MESSAGEMAN:Broadcast("Minimise") + end + return true + end + + -- kb activate chat input if not minimized (has to go after the above enter block) + if event.type == "InputEventType_Release" and INPUTFILTER:IsBeingPressed("left ctrl") then + if event.DeviceInput.button == "DeviceButton_enter" and not minimised then + typing = true + update = true + end + end + + if update then + if minimised then -- minimise will be set in the above blocks, disable input and clear text -mina + typing = false + typingText = "" + end + MESSAGEMAN:Broadcast("UpdateChatOverlay") + end + + -- always eat mouse inputs if its within the broader chatbox + if event.DeviceInput.button == "DeviceButton_left mouse button" and isOver(bg) then + return true + end + + returnInput = update or typing + return returnInput +end + +return chat +--[[ + Untested half done prototype stuff for chart request front end (Probably + wanna put this in a special tab located at the rightmost possible position) + +local chartRequestsConfig = { + numChartReqActors = 4, + padding = 10, + spacing = 10, + height = 1, + width = SCREEN_WIDTH +} +chartRequestsConfig.itemHeight = + (chartRequestsConfig.height - chartRequestsConfig.padding * 2) / chartRequestsConfig.numChartReqActors +chartRequestsConfig.itemWidth = chartRequestsConfig.width - chartRequestsConfig.padding * 2 +function chartRequestActor(i) + local song + local steps + local req + req = + Def.ActorFrame { + y = (chartRequestsConfig.itemHeight + chartRequestsConfig.spacing) * (i - 1) + } + req.sprite = Widg.Sprite {} + req.rateFont = Widg.Label {} + req.songNameFont = Widg.Label {} + req.rect = + Widg.Rectangle { + width = chartRequestsConfig.itemWidth, + height = chartRequestsConfig.itemHeight - chartRequestsConfig.spacing, + onClick = function() + if song and steps then + local screen = SCREENMAN:GetTopScreen() + local sName = screen:GetName() + if sName == "ScreenSelectMusic" or sName == "ScreenNetSelectMusic" then + screen:GetMusicWheel():SelectSong(song) + end + end + end + } + req[#req + 1] = req.sprite + req[#req + 1] = req.rateFont + req[#req + 1] = req.songNameFont + req[#req + 1] = req.rect + req.updateWithRequest = function(req) + if not req then + song = nil + steps = nil + req.actor:visible(false) + return + end + req.actor:visible(true) + + local ck = req:GetChartkey() + local requester = req:GetUser() + local rate = req:GetRate() + + song = SONGMAN:GetSongByChartKey(ck) + steps = SONGMAN:GetStepsByChartKey(ck) + + req.sprite.actor:fadeleft(1) + req.sprite.actor:Load(song:GetBannerPath()) + req.sprite.actor:scaletocover(0, 0, chartRequestsConfig.itemWidth, chartRequestsConfig.itemHeight) + req.rateFont.actor:settext(tostring(rate)) + req.songNameFont.actor:settext(song:GetMainTitle()) + end + return req +end +local bg = + Widg.Rectangle { + width = chartRequestsConfig.width - chartRequestsConfig.padding * 2, + height = chartRequestsConfig.height - chartRequestActor.padding * 2 +} +local t = + Def.Container { + x = chartRequestsConfig.padding, + y = chartRequestsConfig.padding, + content = { + bg + } +} +local reqWidgs = {} +for i = 1, chartRequestsConfig.numChartReqActors do + reqWidgs[#reqWidgs + 1] = chartRequestActor(i) + t[#t + 1] = reqWidgs[#reqWidgs] +end +local offset = 0 +t.ChartRequestMessageCommand = function(self) + local reqs = NSMAN:GetChartRequests() + for i = 1, #reqWidgs do + local widg = reqWidgs[i] + widg.updateWithRequest(reqs[i + offsset]) + end +end +t.BeginCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback( + function(event) + if event.type ~= "InputEventType_FirstPress" or not bg:isOver() then + return false + end + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + offset = math.min(offset - 1, 0) + t.ChartRequestMessageCommand() + elseif event.DeviceInput.button == "DeviceButton_mousewheel down" then + local reqs = NSMAN:GetChartRequests() + offset = math.min(offset + 1, #reqs) + t.ChartRequestMessageCommand() + end + end + ) +end + +]] diff --git a/BGAnimations/ScreenColorChange decorations.lua b/BGAnimations/ScreenColorChange decorations.lua index d46bdab8..6473f93b 100644 --- a/BGAnimations/ScreenColorChange decorations.lua +++ b/BGAnimations/ScreenColorChange decorations.lua @@ -5,15 +5,15 @@ t[#t+1] = Def.Quad{ self:zoomto(SCREEN_WIDTH-25,SCREEN_HEIGHT-60) self:Center() self:diffuse(getMainColor("frame")):diffusealpha(0) - end; + end, OnCommand = function(self) self:smooth(0.5) self:diffusealpha(0.8) - end; + end, OffCommand = function(self) self:smooth(0.5) self:diffusealpha(0) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenColorChange overlay.lua b/BGAnimations/ScreenColorChange overlay.lua index 0bb2e1c8..6479c225 100644 --- a/BGAnimations/ScreenColorChange overlay.lua +++ b/BGAnimations/ScreenColorChange overlay.lua @@ -56,20 +56,20 @@ local function generateCategory() self:zoom(scale) self:halign(0) self:queuecommand('UpdateColor') - end; + end, RowChangedMessageCommand = function(self,params) if params.level == 1 then self:queuecommand('UpdateColor') self:settext(visibleItems[k]) end - end; + end, ColChangedMessageCommand = function(self,params) if params.level == 1 then self:diffusealpha(1) else self:diffusealpha(0.5) end - end; + end, UpdateColorCommand=function(self) if visibleItems[k] == currentItems[1][cursorIndex[1]] then self:diffuse(getMainColor('highlight')) @@ -133,19 +133,19 @@ local function generateCategoryColors() self:zoom(scale) self:halign(0) self:queuecommand('UpdateColor') - end; + end, RowChanged2MessageCommand = function(self,params) if params.level <= 2 then self:queuecommand('UpdateColor') end - end; + end, ColChangedMessageCommand = function(self,params) if params.level == 2 then self:diffusealpha(1) else self:diffusealpha(0.5) end - end; + end, UpdateColorCommand=function(self) if visibleItems[i] ~= nil then self:visible(true) @@ -179,19 +179,19 @@ local function generateCategoryColors() self:zoom(scale) self:halign(0) self:queuecommand('UpdateColor') - end; + end, RowChanged2MessageCommand = function(self,params) if params.level <= 2 then self:queuecommand('UpdateColor') end - end; + end, ColChangedMessageCommand = function(self,params) if params.level == 2 then self:diffusealpha(1) else self:diffusealpha(0.5) end - end; + end, UpdateColorCommand=function(self) if visibleItems[i] ~= nil then self:visible(true) @@ -257,34 +257,34 @@ local t = Def.ActorFrame{ MESSAGEMAN:Broadcast("ColChanged",{level = curLevel}) elseif curLevel == 2 then setTableKeys(selected) - SCREENMAN:AddNewScreenToTop("ScreenColorEdit"); + SCREENMAN:AddNewScreenToTop("ScreenColorEdit") end elseif params.Name == "ColorCancel" then SCREENMAN:GetTopScreen():Cancel() end - end; + end } -t[#t+1] = LoadActor("_frame"); -t[#t+1] = LoadActor("_mouse"); +t[#t+1] = LoadActor("_frame") +t[#t+1] = LoadActor("_mouse") t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:xy(frameX[1],frameY):halign(0):valign(1):zoom(0.6):settext("Category:") - end; + end } t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:xy(frameX[2],frameY):halign(0):valign(1):zoom(0.6):settext("Name:") - end; + end } t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:xy(frameX[3],frameY):halign(0):valign(1):zoom(0.6):settext("Color:") - end; + end } if configData ~= nil then diff --git a/BGAnimations/ScreenColorEdit overlay.lua b/BGAnimations/ScreenColorEdit overlay.lua index baa9fe67..93ed4dff 100644 --- a/BGAnimations/ScreenColorEdit overlay.lua +++ b/BGAnimations/ScreenColorEdit overlay.lua @@ -7,7 +7,7 @@ local themeColor = colorConfig:get_data()[selected[1]][selected[2]] local colorTable = {} for i=2,#themeColor do --First string is a "#", ignore. colorTable[i-1] = themeColor:sub(i,i) -end; +end @@ -21,15 +21,15 @@ local function scroller(index) t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(SCREEN_CENTER_X-60+index*20,SCREEN_CENTER_Y):zoom(0.8) - end; + end, OnCommand=function(self) self:settext(string.format("%01X",number or 0)) if index == cursor then self:diffuse(color("#FFFFFF")) else self:diffuse(color("#666666")) - end; - end; + end + end, CodeMessageCommand=function(self,params) if params.Name == "ColorUp" then if index == cursor then @@ -66,7 +66,7 @@ local function scroller(index) self:diffuse(color("#666666")) end end - end; + end } return t @@ -97,26 +97,26 @@ local t = Def.ActorFrame{ if params.Name == "ColorLeft" then cursor = ((cursor-2)%(count))+1 end - end; + end } t[#t+1] = Def.Quad{ InitCommand=function(self) self:xy(0,0):halign(0):valign(0):zoomto(SCREEN_WIDTH,SCREEN_HEIGHT):diffuse(getMainColor("frame")):diffusealpha(0.6) - end; -}; + end +} -t[#t+1] = LoadActor("_frame"); -t[#t+1] = LoadActor("_mouse"); +t[#t+1] = LoadActor("_frame") +t[#t+1] = LoadActor("_mouse") t[#t+1] = Def.Quad{ InitCommand=function(self) self:xy(SCREEN_CENTER_X,SCREEN_CENTER_Y+40):zoomto(200,30) - end; + end, OnCommand=function(self) self:diffuse(color(themeColor)) - end; + end, CodeMessageCommand=function(self,params) if params.Name == "ColorUp" then self:queuecommand("SetColor") @@ -124,30 +124,30 @@ t[#t+1] = Def.Quad{ if params.Name == "ColorDown" then self:queuecommand("SetColor") end - end; + end, SetColorCommand=function(self) self:diffuse(color("#"..table.concat(colorTable))) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(SCREEN_CENTER_X-60,SCREEN_CENTER_Y):zoom(0.8) - end; + end, OnCommand=function(self) self:settext("#") self:diffuse(color("#666666")) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(SCREEN_CENTER_X,SCREEN_CENTER_Y+100):zoom(0.4) - end; + end, OnCommand=function(self) self:settextf("%s \"%s - %s\".\n\n%s",THEME:GetString("ScreenColorEdit","Description1"),selected[1],selected[2],THEME:GetString("ScreenColorEdit","Description2")) self:diffuse(color("#FFFFFF")) - end; + end } for i=1,6 do diff --git a/BGAnimations/ScreenDownload overlay/default.lua b/BGAnimations/ScreenDownload overlay/default.lua index c543990d..3f01932b 100644 --- a/BGAnimations/ScreenDownload overlay/default.lua +++ b/BGAnimations/ScreenDownload overlay/default.lua @@ -1,40 +1,94 @@ local top -local packlist = DLMAN:GetPackList() +local initpacklist = PackList:new() +local packlist = initpacklist:GetPackTable() local downloading = DLMAN:GetDownloadingPacks() -- make lookup table for installed packs local installedPacks = {} -for k,v in pairs(SONGMAN:GetSongGroupNames()) do - installedPacks[v] = true +local function refreshInstalledPacks() + for k,v in pairs(SONGMAN:GetSongGroupNames()) do + installedPacks[v] = true + end +end +refreshInstalledPacks() + +local function packExists(group) + if installedPacks[group] then + return true + end end local maxItems = 10 local maxPages = math.ceil(#packlist/maxItems) local curPage = 1 +local sorts = { + "ABC", + "MSD", + "Size", + "Installed" +} +local curSort = 1 +local ascending = true +local function moveSortForward() + curSort = (curSort % 4) + 1 +end -local function movePage(n) - if n > 0 then - curPage = ((curPage+n-1) % maxPages + 1) +local function sortPacks() + local rawsort = false + if sorts[curSort] == "ABC" then + initpacklist:SortByName() + elseif sorts[curSort] == "MSD" then + initpacklist:SortByDiff() + elseif sorts[curSort] == "Size" then + initpacklist:SortBySize() else - curPage = ((curPage+n+maxPages-1) % maxPages+1) + ascending = not ascending + table.sort(packlist, function(left, right) + if not packExists(left:GetName()) and not packExists(right:GetName()) then + return left:GetName() < right:GetName() + else + if ascending then + return packExists(left:GetName()) and not packExists(right:GetName()) + else + return not packExists(left:GetName()) and packExists(right:GetName()) + end + end + end) + rawsort = true + end + if not rawsort then + packlist = initpacklist:GetPackTable() end - MESSAGEMAN:Broadcast("UpdateList") end -local function packExists(group) - if installedPacks[group] then - return true +local curInput = "" +local inputting = false + +local function movePage(n) + if maxPages > 1 then + if n > 0 then + curPage = ((curPage+n-1) % maxPages + 1) + else + curPage = ((curPage+n+maxPages-1) % maxPages+1) + end end + MESSAGEMAN:Broadcast("UpdateList") +end + +local function updateFilter() + initpacklist:FilterAndSearch( + tostring(curInput), 0, 0, 0, 0 + ) + packlist = initpacklist:GetPackTable() + maxPages = math.ceil(#packlist/maxItems) + MESSAGEMAN:Broadcast("UpdateList") end local function input(event) if event.type == "InputEventType_FirstPress" then - if event.button == "Back" or event.button == "Start" then - SCREENMAN:GetTopScreen():Cancel() - end if event.button == "MenuLeft" then movePage(-1) @@ -44,6 +98,45 @@ local function input(event) movePage(1) end + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + end + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + end + + if inputting then + if event.button == "Start" then + inputting = false + elseif event.button == "Back" then + curInput = "" + inputting = false + updateFilter() + elseif event.DeviceInput.button == "DeviceButton_backspace" then + curInput = curInput:sub(1, -2) + updateFilter() + elseif event.DeviceInput.button == "DeviceButton_delete" then + curInput = "" + updateFilter() + elseif event.DeviceInput.button == "DeviceButton_space" then + curInput = curInput .. " " + updateFilter() + elseif event.DeviceInput.button == "DeviceButton_left mouse button" or event.DeviceInput.button == "DeviceButton_right mouse button" then + inputting = false + else + if event.char and event.char:match('[%%%+%-%!%@%#%$%^%&%*%(%)%=%_%.%,%:%;%\'%"%>%<%?%/%~%|%w]') and event.char ~= "" then + curInput = curInput .. event.char + updateFilter() + end + end + MESSAGEMAN:Broadcast("UpdateText") + return true + end + + if event.button == "Back" or event.button == "Start" then + SCREENMAN:GetTopScreen():Cancel() + end + end return false @@ -66,7 +159,9 @@ local t = Def.ActorFrame { top:AddInputCallback(input) self:SetUpdateFunction(update) MESSAGEMAN:Broadcast("UpdateList") - end; + MESSAGEMAN:Broadcast("UpdateBundleList") + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end } @@ -74,6 +169,29 @@ local t = Def.ActorFrame { local function packInfo() local frameWidth = 300 local frameHeight = SCREEN_HEIGHT - 60 + + local packItemWidth = frameWidth-30 + local packItemHeight = 25 + + local packItemX = 20 + local packItemY = 70+packItemHeight/2 + local packItemYSpacing = 5 + + local bundlenames = { + "Novice", + "Novice-Expanded", + "Beginner", + "Beginner-Expanded", + "Intermediate", + "Intermediate-Expanded", + "Advanced", + "Advanced-Expanded", + "Expert", + "Expert-Expanded" + } + + local diffcolors = {"#66ccff", "#099948", "#ddaa00", "#ff6666", "#c97bff"} + local t = Def.ActorFrame{} t[#t+1] = Def.Quad{ @@ -91,28 +209,198 @@ local function packInfo() self:zoom(0.4) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - self:settext("Pack Info") - end; + self:settext("Simfile Pack Bundles") + end } - t[#t+1] = Def.Quad{ - InitCommand = function (self) - self:zoomto(256,80) - self:xy(frameWidth/2, 50):valign(0) - self:diffuse(getMainColor("frame")) - self:diffusealpha(0.8) + -- The extra text in the Bundles section + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(5, 25) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Click to filter the packs for each bundle.") + end + } + + -- The Reset Filter Button + t[#t+1] = quadButton(6) .. { + Name = "ResetFilter", + InitCommand = function(self) + self:xy(packItemX, packItemY - packItemHeight - packItemYSpacing) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(packItemWidth / 4, packItemHeight - packItemYSpacing) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + curPage = 1 + initpacklist:FilterAndSearch( + "", 0, 0, 0, 0 + ) + packlist = initpacklist:GetPackTable() + maxPages = math.ceil(#packlist/maxItems) + curInput = "" + MESSAGEMAN:Broadcast("UpdateList") + end } + -- The Reset Filter Button Text t[#t+1] = LoadFont("Common Bold")..{ - InitCommand = function(self) - self:xy(frameWidth/2, 80+50+10) - self:zoom(0.4) + InitCommand = function(self) + self:xy(packItemX + packItemWidth / 8, packItemY - packItemHeight - packItemYSpacing) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - self:settext("A REALLY LONG SIMFILE PACK TITLE") - end; + self:zoom(0.4) + self:settextf("Reset Filter") + end } + local function bundleItem(i) + local bundle + local bundleIndex = (curPage-1)*10+i + + local t = Def.ActorFrame{ + InitCommand = function(self) + self:diffusealpha(0) + self:xy(packItemX, packItemY + (i-1)*(packItemHeight+packItemYSpacing)-10) + self:playcommand("Show") + end, + ShowCommand = function(self) + self:y(packItemY + (i-1)*(packItemHeight+packItemYSpacing)-10) + self:diffusealpha(0) + self:finishtweening() + self:sleep((i-1)*0.03) + self:easeOut(1) + self:y(packItemY + (i-1)*(packItemHeight+packItemYSpacing)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + end, + UpdateBundleListMessageCommand = function(self) -- Bundle List updates (e.g. new page) + bundleIndex = (curPage-1)*10+i + if DLMAN:GetCoreBundle(bundlenames[bundleIndex]:lower()) ~= nil then + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + } + + -- Bundle index number + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(-10,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + end, + SetCommand = function(self) + self:settextf("%d", bundleIndex) + end + } + + -- The Bundle button + t[#t+1] = quadButton(6) .. { + Name = "Size", + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(packItemWidth, packItemHeight) + end, + TopPressedCommand = function(self) + initpacklist:SetFromCoreBundle(bundlenames[bundleIndex]:lower()) + packlist = initpacklist:GetPackTable() + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + maxPages = math.ceil(#packlist/maxItems) + MESSAGEMAN:Broadcast("UpdateList") + end, + SetCommand = function(self) + self:diffusealpha(0.2) + end + } + + -- Color of the tab for the bundle (based on MSD) + t[#t+1] = Def.Quad{ + Name = "Status", + InitCommand = function(self) + self:halign(0) + self:diffuse(color(colorConfig:get_data().main.highlight)) + self:diffusealpha(0.8) + self:xy(0, 0) + self:zoomto(3, packItemHeight) + end, + SetCommand = function(self) + self:diffuse(byMSD(packlist.AveragePackDifficulty)):diffusealpha(0.8) + end + } + + -- MSD average for the Bundle + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(20,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + -- World's laziest code + initpacklist:SetFromCoreBundle(bundlenames[bundleIndex]:lower()) + packlist = initpacklist:GetPackTable() + local msd = packlist.AveragePackDifficulty + self:settextf("%5.2f",msd) + self:diffuse(getMSDColor(msd)) + initpacklist:FilterAndSearch( + "", 0, 0, 0, 0 + ) + packlist = initpacklist:GetPackTable() + end + } + + -- Bundle name + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(40,-6):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + self:settext(bundlenames[bundleIndex]:gsub("-Expanded", " (expanded)")) + self:maxwidth(packItemWidth * 2) + end + } + + -- Bundle file size + t[#t+1] = LoadFont("Common Normal")..{ + Name = "Size", + InitCommand = function(self) + self:xy(40,5):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + end, + SetCommand = function(self) + local bundle = DLMAN:GetCoreBundle(bundlenames[bundleIndex]:lower()) + self:settextf("%d MB", bundle["TotalSize"]) + end + } + + + return t + end + + for i=1, #bundlenames do + t[#t+1] = bundleItem(i) + end + return t end @@ -120,21 +408,47 @@ local function packList() local frameWidth = 430 local frameHeight = SCREEN_HEIGHT - 60 + -- Pack item information + local packItemWidth = frameWidth-30 + local packItemHeight = 25 + + local packItemX = 20 + local packItemY = 70+packItemHeight/2 + local packItemYSpacing = 5 + ---- + local t = Def.ActorFrame{ DownloadStatusCommand = function(self, params) self:RunCommandsOnChildren(function(self) self:playcommand("DownloadStatus", params) end) - end; + end, + DFRFinishedMessageCommand = function(self) -- Download Finished, a Diff Reload happens (forced by the game) + refreshInstalledPacks() + downloading = DLMAN:GetDownloadingPacks() + MESSAGEMAN:Broadcast("UpdateList") + end, } + -- The background quad for the Packs section t[#t+1] = Def.Quad{ InitCommand = function (self) self:zoomto(frameWidth,frameHeight) self:halign(0):valign(0) self:diffuse(getMainColor("frame")) self:diffusealpha(0.8) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() then + movePage(1) + end end } + -- The text in the top left of the Packs section t[#t+1] = LoadFont("Common Bold")..{ InitCommand = function(self) self:xy(5, 10) @@ -142,15 +456,125 @@ local function packList() self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Simfile Packs") - end; + end } - local packItemWidth = frameWidth-30 - local packItemHeight = 25 + -- The extra text in the Packs section + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(5, 25) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Click to download a pack. Searching for a pack resets the bundle filter.") + end + } - local packItemX = 20 - local packItemY = 70+packItemHeight/2 - local packItemYSpacing = 5 + -- The sort toggle button + t[#t+1] = quadButton(6) .. { + Name = "Sort", + InitCommand = function(self) + self:xy(packItemX - 15, packItemY - packItemHeight - packItemYSpacing) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(packItemWidth / 6, packItemHeight - packItemYSpacing) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + moveSortForward() + sortPacks() + curPage = 1 + MESSAGEMAN:Broadcast("UpdateList") + end + } + + -- The sort text + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(packItemX - 12, packItemY - packItemHeight - packItemYSpacing):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:settextf("Sort: %s", sorts[curSort]) + self:maxwidth(packItemWidth / 3 + 15) + end, + UpdateListMessageCommand = function(self) + self:settextf("Sort: %s", sorts[curSort]) + end + } + + -- Sort Ascending/Descending button + t[#t+1] = quadButton(6) .. { + Name = "ToggleAscending", + InitCommand = function(self) + self:xy(packItemX + packItemWidth / 6 - 10, packItemY - packItemHeight - packItemYSpacing) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(packItemWidth / 6, packItemHeight - packItemYSpacing) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + sortPacks() + curPage = 1 + MESSAGEMAN:Broadcast("UpdateList") + end + } + + -- The toggle ascending/descending text + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(packItemX + 60, packItemY - packItemHeight - packItemYSpacing):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:settext("Toggle Ascending", sorts[curSort]) + self:maxwidth(packItemWidth / 3 + 15) + end + } + + -- The search-by-name box + t[#t+1] = quadButton(6) .. { + Name = "Search", + InitCommand = function(self) + self:xy(packItemX + 128, packItemY - packItemHeight - packItemYSpacing) + self:halign(0) + self:zoomto(packItemWidth - 128, packItemHeight - packItemYSpacing) + self:diffusealpha(0.2) + end, + TopPressedCommand = function(self) + self:diffusealpha(0.4) + inputting = true + end, + UpdateTextMessageCommand = function(self) + if inputting then + self:diffusealpha(0.4) + else + self:diffusealpha(0.2) + end + end + } + + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(packItemX + 131, packItemY - packItemHeight - packItemYSpacing):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:settext("Click to Start Typing") + self:maxwidth(packItemWidth * 1.65) + end, + UpdateListMessageCommand = function(self) + if curInput ~= "" then + self:settextf("%s", curInput) + else + self:settext("Click to Start Typing") + end + end + } + local function packItem(i) local download @@ -161,7 +585,7 @@ local function packList() self:diffusealpha(0) self:xy(packItemX, packItemY + (i-1)*(packItemHeight+packItemYSpacing)-10) self:playcommand("Show") - end; + end, ShowCommand = function(self) self:y(packItemY + (i-1)*(packItemHeight+packItemYSpacing)-10) self:diffusealpha(0) @@ -170,12 +594,12 @@ local function packList() self:easeOut(1) self:y(packItemY + (i-1)*(packItemHeight+packItemYSpacing)) self:diffusealpha(1) - end; + end, HideCommand = function(self) self:stoptweening() self:easeOut(0.5) self:diffusealpha(0) - end; + end, UpdateListMessageCommand = function(self) -- Pack List updates (e.g. new page) packIndex = (curPage-1)*10+i if packlist[packIndex] ~= nil then @@ -184,7 +608,7 @@ local function packList() else self:playcommand("Hide") end - end; + end, DownloadStatusCommand = function(self, params) -- Download status update from updatefunction if not params.download then return @@ -198,78 +622,71 @@ local function packList() self:GetChild("Size"):settextf("Downloading %5.2f MB / %5.2f MB", download:GetKBDownloaded()/1048576, download:GetTotalKB()/1048576) self:GetChild("ProgressBar"):zoomx(download:GetKBDownloaded()/download:GetTotalKB()*packItemWidth) end - end; + end, StartDownloadCommand = function(self) -- Start download download = packlist[packIndex]:DownloadAndInstall() - - -- Will crash the game if the pack is already downloaded for the time being. downloading = DLMAN:GetDownloadingPacks() - - self:GetChild("Status"):diffuse(color(colorConfig:get_data().downloadStatus.downloading)):diffusealpha(0.8) - self:GetChild("ProgressBar"):diffuse(color(colorConfig:get_data().downloadStatus.downloading)):diffusealpha(0.2) - end; + if not packExists(packlist[packIndex]:GetName()) then + self:GetChild("Status"):diffuse(color(colorConfig:get_data().downloadStatus.downloading)):diffusealpha(0.8) + self:GetChild("ProgressBar"):diffuse(color(colorConfig:get_data().downloadStatus.downloading)):diffusealpha(0.2) + end + end, StopDownloadCommand = function(self) -- Stop download download:Stop() downloading = DLMAN:GetDownloadingPacks() - self:GetChild("Status"):playcommand("Set") - self:GetChild("ProgressBar"):diffuse(color(colorConfig:get_data().downloadStatus.available)):diffusealpha(0.2) - self:GetChild("Size"):settextf("Download Cancelled") - end; - FinishDownloadCommand = function(self) -- Download Finished - downloading = DLMAN:GetDownloadingPacks() - self:GetChild("Status"):diffuse(color(colorConfig:get_data().downloadStatus.completed)):diffusealpha(0.8) - self:GetChild("ProgressBar"):diffuse(color(colorConfig:get_data().downloadStatus.completed)):diffusealpha(0.2) - self:GetChild("Size"):settextf("Download Complete!") - end; + end, PackDownloadedMessageCommand = function(self, params) -- Download Stopped/Finished downloading = DLMAN:GetDownloadingPacks() - end; + end, DownloadFailedMessageCommand = function(self, params) -- Download Failed - if packlist[packIndex]:GetName() == params.pack:GetName() then + if packlist[packIndex] ~= nil and packlist[packIndex]:GetName() == params.pack:GetName() then downloading = DLMAN:GetDownloadingPacks() self:GetChild("Status"):playcommand("Set") self:GetChild("ProgressBar"):diffuse(color(colorConfig:get_data().downloadStatus.available)):diffusealpha(0.2) - self:GetChild("Size"):settextf("Download Failed") + self:GetChild("Size"):settextf("Download Failed or Cancelled") end - end; + end } + -- Pack index number t[#t+1] = LoadFont("Common Normal")..{ InitCommand = function(self) self:xy(-10,0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) - end; + end, SetCommand = function(self) self:settextf("%d", packIndex) - end; + end } + -- The download progress bar (background of the pack buttons) t[#t+1] = Def.Quad{ - Name = "ProgressBar"; + Name = "ProgressBar", InitCommand = function(self) self:halign(0) self:diffuse(color(colorConfig:get_data().main.highlight)) self:diffusealpha(0) self:xy(0, 0) self:zoomy(packItemHeight) - end; + end, SetCommand = function(self) self:zoomx(0) - end; + end } + -- The pack button t[#t+1] = quadButton(6) .. { - Name = "Size"; + Name = "Size", InitCommand = function(self) self:halign(0) self:diffusealpha(0.2) self:zoomto(packItemWidth, packItemHeight) - end; + end, TopPressedCommand = function(self) - if packlist[packIndex]:IsDownloading() then -- IsDownloading() returns the wrong boolean for some reason. + if packlist[packIndex] ~= nil and packlist[packIndex]:IsDownloading() then -- IsDownloading() returns the wrong boolean for some reason. self:GetParent():playcommand("StartDownload") - else + elseif packlist[packIndex] ~= nil then self:GetParent():playcommand("StopDownload") end @@ -277,38 +694,39 @@ local function packList() self:diffusealpha(0.4) self:smooth(0.3) self:diffusealpha(0.2) - end; + end, SetCommand = function(self) self:diffusealpha(0.2) - end; + end } + -- Color of the tab for the pack (downloaded/not downloaded) t[#t+1] = Def.Quad{ - Name = "Status"; + Name = "Status", InitCommand = function(self) self:halign(0) self:diffuse(color(colorConfig:get_data().main.highlight)) self:diffusealpha(0.8) self:xy(0, 0) self:zoomto(3, packItemHeight) - end; + end, SetCommand = function(self) if packExists(packlist[packIndex]:GetName()) then self:diffuse(color(colorConfig:get_data().downloadStatus.downloaded)):diffusealpha(0.8) else self:diffuse(color(colorConfig:get_data().downloadStatus.available)):diffusealpha(0.8) end - end; + end } - + -- MSD average for the pack t[#t+1] = LoadFont("Common Bold")..{ InitCommand = function(self) self:xy(20,0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) - end; + end, SetCommand = function(self) local msd = packlist[packIndex]:GetAvgDifficulty() self:settextf("%5.2f",msd) @@ -316,27 +734,33 @@ local function packList() end } + -- Pack name t[#t+1] = LoadFont("Common Bold")..{ InitCommand = function(self) self:xy(40,-6):halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) - end; + end, SetCommand = function(self) self:settextf("%s",packlist[packIndex]:GetName()) + + -- The pack names can get really long. Set the max width to double the button width + -- because not setting it to double the width makes the text half the width ???? + self:maxwidth(packItemWidth * 2) end } + -- Pack file size t[#t+1] = LoadFont("Common Normal")..{ - Name = "Size"; + Name = "Size", InitCommand = function(self) self:xy(40,5):halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) - end; + end, SetCommand = function(self) if packExists(packlist[packIndex]:GetName()) then - self:settext("Downloaded (Or a pack with an identical name exists)") + self:settext("Installed (Or a pack with an identical name exists)") else self:settextf("Download %5.2f MB",packlist[packIndex]:GetSize()/1048576) end @@ -364,7 +788,7 @@ t[#t+1] = packInfo() .. { } t[#t+1] = packList() .. { - Name = "PackList"; + Name = "PackList", InitCommand = function(self) self:xy(320,30) self:delayedFadeIn(2) diff --git a/BGAnimations/ScreenEditMenu decorations.lua b/BGAnimations/ScreenEditMenu decorations.lua index d46bdab8..e69de29b 100644 --- a/BGAnimations/ScreenEditMenu decorations.lua +++ b/BGAnimations/ScreenEditMenu decorations.lua @@ -1,19 +0,0 @@ -local t = Def.ActorFrame{} - -t[#t+1] = Def.Quad{ - InitCommand = function(self) - self:zoomto(SCREEN_WIDTH-25,SCREEN_HEIGHT-60) - self:Center() - self:diffuse(getMainColor("frame")):diffusealpha(0) - end; - OnCommand = function(self) - self:smooth(0.5) - self:diffusealpha(0.8) - end; - OffCommand = function(self) - self:smooth(0.5) - self:diffusealpha(0) - end; -} - -return t \ No newline at end of file diff --git a/BGAnimations/ScreenEvaluation decorations/MPscoreboard.lua b/BGAnimations/ScreenEvaluation decorations/MPscoreboard.lua new file mode 100644 index 00000000..349d4ae3 --- /dev/null +++ b/BGAnimations/ScreenEvaluation decorations/MPscoreboard.lua @@ -0,0 +1,241 @@ +local lines = 10 -- number of scores to display +local frameWidth = 260 +local framex = SCREEN_WIDTH-frameWidth-WideScale(get43size(40),40)/2 +local framey = 110 +local spacing = 34 + +--Input event for mouse clicks +local function input(event) + local scoreBoard = SCREENMAN:GetTopScreen():GetChildren().scoreBoard + if event.DeviceInput.button == "DeviceButton_left mouse button" and scoreBoard then + if event.type == "InputEventType_Release" then + for i = 1, #multiscores do + if isOver(scoreBoard:GetChildren()[tostring(i)]:GetChild("mouseOver")) then + --SCREENMAN:GetTopScreen():SetCurrentPlayer(i) + scoreBoard:GetChild(i):GetChild("grade"):visible(not scoreBoard:GetChild(i):GetChild("grade"):GetVisible()) + scoreBoard:GetChild(i):GetChild("clear"):visible(not scoreBoard:GetChild(i):GetChild("clear"):GetVisible()) + scoreBoard:GetChild(i):GetChild("wife"):visible(not scoreBoard:GetChild(i):GetChild("wife"):GetVisible()) + scoreBoard:GetChild(i):GetChild("combo"):visible(not scoreBoard:GetChild(i):GetChild("combo"):GetVisible()) + scoreBoard:GetChild(i):GetChild("judge"):visible(not scoreBoard:GetChild(i):GetChild("judge"):GetVisible()) + scoreBoard:GetChild(i):GetChild("option"):visible(not scoreBoard:GetChild(i):GetChild("option"):GetVisible()) + end + end + end + end + return false +end + +local function Update(self) + for i = 1, lines do + if isOver(self:GetChild(i):GetChild("mouseOver")) then + self:GetChild(i):GetChild("mouseOver"):diffusealpha(0.2) + else + self:GetChild(i):GetChild("mouseOver"):diffusealpha(0) + self:GetChild(i):GetChild("grade"):visible(true) + self:GetChild(i):GetChild("wife"):visible(true) + self:GetChild(i):GetChild("combo"):visible(true) + self:GetChild(i):GetChild("judge"):visible(true) + self:GetChild(i):GetChild("clear"):visible(true) + self:GetChild(i):GetChild("option"):visible(false) + end + end +end + +local sortFunction = function(first, second) + return first["highscore"]:GetWifeScore() > second["highscore"]:GetWifeScore() +end + +local t = + Def.ActorFrame { + Name = "scoreBoard", + InitCommand = function(self) + self:SetUpdateFunction(Update) + end, + BeginCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(input) + multiscores = NSMAN:GetEvalScores() + table.sort(multiscores, sortFunction) + for i = 1, math.min(#multiscores) do + self:GetChild(i):queuecommand("UpdateNetScore") + end + end, + NewMultiScoreMessageCommand = function(self) + multiscores = NSMAN:GetEvalScores() + table.sort(multiscores, sortFunction) + for i = 1, math.min(#multiscores) do + self:GetChild(i):queuecommand("UpdateNetScore") + end + end +} + +local function scoreitem(pn, i) + local t = + Def.ActorFrame { + Name = tostring(i), + InitCommand = function(self) + self:visible(false) + end, + UpdateNetScoreCommand = function(self) + self:visible(i <= #multiscores) + end, + --The main quad + Def.Quad { + InitCommand = function(self) + self:xy(framex, framey + ((i - 1) * spacing) - 4):zoomto(frameWidth, 30):halign(0):valign(0):diffuse(getMainColor("frame")):diffusealpha(0.8) + end + }, + --Highlight quad for the current score + Def.Quad { + InitCommand = function(self) + self:xy(framex, framey + ((i - 1) * spacing) - 4):zoomto(frameWidth, 30):halign(0):valign(0):diffuse(getMainColor("highlight")):diffusealpha(0.3) + end, + UpdateNetScoreCommand = function(self) + self:visible(SCREENMAN:GetTopScreen():GetCurrentPlayer() == i) + end, + UpdateNetEvalStatsMessageCommand = function(self) + self:visible(SCREENMAN:GetTopScreen():GetCurrentPlayer() == i) + end + }, + --Quad that will act as the bounding box for mouse rollover/click stuff. + Def.Quad { + Name = "mouseOver", + UpdateNetScoreCommand = function(self) + self:xy(framex, framey + ((i - 1) * spacing) - 4):zoomto(frameWidth * 2, 30):halign(0):valign(0):diffuse( + getMainColor("highlight") + ):diffusealpha(0.05) + end + }, + --ClearType lamps + Def.Quad { + UpdateNetScoreCommand = function(self) + self:xy(framex, framey + ((i - 1) * spacing) - 4):zoomto(8, 30):halign(0):valign(0):diffuse( + getClearTypeFromScore(pn, hs, 2) + ) + end + }, + --rank + LoadFont("Common normal") .. + { + InitCommand = function(self) + self:xy(framex - 8, framey + 12 + ((i - 1) * spacing)):zoom(0.35) + end, + UpdateNetScoreCommand = function(self) + self:settext(i) + if SCREENMAN:GetTopScreen():GetCurrentPlayer() == i then + self:diffuseshift() + self:effectcolor1(color(colorConfig:get_data().evaluation.BackgroundText)) + self:effectcolor2(color("#3399cc")) + self:effectperiod(0.1) + else + self:stopeffect() + self:diffuse(color(colorConfig:get_data().evaluation.BackgroundText)) + end + end, + UpdateNetEvalStatsMessageCommand = function(self) + self:playcommand("UpdateNetScore") + end + }, + LoadFont("Common normal") .. + { + Name = "wife", + InitCommand = function(self) + self:xy(framex + 10, framey + 11 + ((i - 1) * spacing)):zoom(0.35):halign(0):maxwidth((frameWidth - 15) / 0.3) + end, + UpdateNetScoreCommand = function(self) + self:settextf( + "%05.2f%% (%s) - %sx", + notShit.floor(multiscores[i].highscore:GetWifeScore() * 10000) / 100, + "Wife", + string.format("%.2f", multiscores[i].highscore:GetMusicRate()):gsub("%.?0+$", "") + ) + end + }, + LoadFont("Common normal") .. + { + Name = "user", + InitCommand = function(self) + self:xy(framex + 10, framey + 1 + ((i - 1) * spacing)):zoom(0.35):halign(0):maxwidth((frameWidth - 15) / 0.3) + end, + UpdateNetScoreCommand = function(self) + self:settextf(multiscores[i].user) + if Grade:Reverse()[GetGradeFromPercent(multiscores[i].highscore:GetWifeScore())] < 2 then -- this seeems right -mina + self:rainbowscroll(true) + end + end + }, + LoadFont("Common normal") .. + { + Name = "option", + InitCommand = function(self) + self:xy(framex + 10, framey + 11 + ((i - 1) * spacing)):zoom(0.35):halign(0):maxwidth((frameWidth - 15) / 0.35) + end, + UpdateNetScoreCommand = function(self) + self:settext(multiscores[i].highscore:GetModifiers()) + self:visible(false) + end + }, + LoadFont("Common normal") .. + { + Name = "grade", + InitCommand = function(self) + self:xy(framex + 130 + capWideScale(get43size(0), 50), framey + 2 + ((i - 1) * spacing)):zoom(0.35):halign(0.5):maxwidth( + (frameWidth - 15) / 0.35 + ) + end, + UpdateNetScoreCommand = function(self) + self:settext(getGradeStrings(multiscores[i].highscore:GetWifeGrade())) + self:diffuse(getGradeColor(multiscores[i].highscore:GetWifeGrade())) + end + }, + LoadFont("Common normal") .. + { + Name = "clear", + InitCommand = function(self) + self:xy(framex + 130 + capWideScale(get43size(0), 50), framey + 12 + ((i - 1) * spacing)):zoom(0.35):halign(0.5):maxwidth( + (frameWidth - 15) / 0.35 + ) + end, + UpdateNetScoreCommand = function(self) + self:settext(getClearTypeFromScore(pn, multiscores[i].highscore, 0)) + self:diffuse(getClearTypeFromScore(pn, multiscores[i].highscore, 2)) + end + }, + LoadFont("Common normal") .. + { + Name = "combo", + InitCommand = function(self) + self:xy(framex + 130 + capWideScale(get43size(0), 50), framey + 21 + ((i - 1) * spacing)):zoom(0.35):halign(0.5):maxwidth( + (frameWidth - 15) / 0.35 + ) + end, + UpdateNetScoreCommand = function(self) + self:settextf("%sx", multiscores[i].highscore:GetMaxCombo()) + end + }, + LoadFont("Common normal") .. + { + Name = "judge", + InitCommand = function(self) + self:xy(framex + 10, framey + 20 + ((i - 1) * spacing)):zoom(0.35):halign(0):maxwidth((frameWidth - 15) / 0.35) + end, + UpdateNetScoreCommand = function(self) + self:settextf( + "%d / %d / %d / %d / %d / %d", + multiscores[i].highscore:GetTapNoteScore("TapNoteScore_W1"), + multiscores[i].highscore:GetTapNoteScore("TapNoteScore_W2"), + multiscores[i].highscore:GetTapNoteScore("TapNoteScore_W3"), + multiscores[i].highscore:GetTapNoteScore("TapNoteScore_W4"), + multiscores[i].highscore:GetTapNoteScore("TapNoteScore_W5"), + multiscores[i].highscore:GetTapNoteScore("TapNoteScore_Miss") + ) + end + } + } + return t +end + +for i = 1, lines do + t[#t + 1] = scoreitem(1, i) +end + +return t diff --git a/BGAnimations/ScreenEvaluation decorations/default.lua b/BGAnimations/ScreenEvaluation decorations/default.lua index 66cc20ed..000a4158 100644 --- a/BGAnimations/ScreenEvaluation decorations/default.lua +++ b/BGAnimations/ScreenEvaluation decorations/default.lua @@ -1,5 +1,7 @@ local t = Def.ActorFrame{} local song = GAMESTATE:GetCurrentSong() +local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(PLAYER_1) +local steps = GAMESTATE:GetCurrentSteps(pn) --ScoreBoard local judges = {'TapNoteScore_W1','TapNoteScore_W2','TapNoteScore_W3','TapNoteScore_W4','TapNoteScore_W5','TapNoteScore_Miss'} @@ -9,13 +11,56 @@ local frameY = 150 local frameWidth = SCREEN_CENTER_X-WideScale(get43size(40),40) local frameHeight = 300 local rate = getCurRate() +local judge = GetTimingDifficulty() -- Reset preview music starting point since song was finished. GHETTOGAMESTATE:setLastPlayedSecond(0) --- ApproachSecond time for all rolling numbers in this file. -local approachSecond = 0.5 - +-- etc timing info +local nrv = pss:GetNoteRowVector() +local dvt = pss:GetOffsetVector() +local ctt = pss:GetTrackVector() +local ntt = pss:GetTapNoteTypeVector() +local totalTaps = pss:GetTotalTaps() + +local rescoredPercentage + +local t = Def.ActorFrame {} + +t[#t+1] = Def.ActorFrame { + OffsetPlotModificationMessageCommand = function(self, params) + local score = pss:GetHighScore() + local totalHolds = + pss:GetRadarPossible():GetValue("RadarCategory_Holds") + pss:GetRadarPossible():GetValue("RadarCategory_Rolls") + local holdsHit = + score:GetRadarValues():GetValue("RadarCategory_Holds") + score:GetRadarValues():GetValue("RadarCategory_Rolls") + local minesHit = + pss:GetRadarPossible():GetValue("RadarCategory_Mines") - score:GetRadarValues():GetValue("RadarCategory_Mines") + if enabledCustomWindows then + if params.Name == "PrevJudge" then + judge = judge < 2 and #customWindows or judge - 1 + customWindow = timingWindowConfig:get_data()[customWindows[judge]] + rescoredPercentage = getRescoredCustomPercentage(dvt, customWindow, totalHolds, holdsHit, minesHit, totalTaps) + elseif params.Name == "NextJudge" then + judge = judge == #customWindows and 1 or judge + 1 + customWindow = timingWindowConfig:get_data()[customWindows[judge]] + rescoredPercentage = getRescoredCustomPercentage(dvt, customWindow, totalHolds, holdsHit, minesHit, totalTaps) + end + elseif params.Name == "PrevJudge" and judge > 1 then + judge = judge - 1 + rescoredPercentage = getRescoredWifeJudge(dvt, judge, totalHolds - holdsHit, minesHit, totalTaps) + elseif params.Name == "NextJudge" and judge < 9 then + judge = judge + 1 + rescoredPercentage = getRescoredWifeJudge(dvt, judge, totalHolds - holdsHit, minesHit, totalTaps) + end + if params.Name == "ResetJudge" then + judge = enabledCustomWindows and 0 or GetTimingDifficulty() + self:GetParent():playcommand("ResetJudge") + elseif params.Name ~= "ToggleHands" then + self:GetParent():playcommand("SetJudge", params) + end + end +} -- Timing/Judge Difficulty t[#t+1] = LoadFont("Common Normal")..{ @@ -24,7 +69,16 @@ t[#t+1] = LoadFont("Common Normal")..{ self:zoom(0.4) self:halign(0) self:diffuse(color(colorConfig:get_data().evaluation.BackgroundText)):diffusealpha(0.8) - self:settextf("Timing Difficulty: %d",GetTimingDifficulty()) + self:queuecommand("Set") + end, + SetCommand = function(self) + self:settextf("Timing Difficulty: %d",judge) + end, + SetJudgeCommand = function(self) + self:queuecommand("Set") + end, + ResetJudgeCommand = function(self) + self:queuecommand("Set") end } @@ -50,6 +104,19 @@ t[#t+1] = LoadFont("Common Normal")..{ end } +-- Mod List +t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(10,85) + self:zoom(0.4) + self:halign(0) + self:maxwidth(SCREEN_WIDTH - (266/2) - 45) + self:diffuse(color(colorConfig:get_data().evaluation.BackgroundText)):diffusealpha(0.8) + local mods = GAMESTATE:GetPlayerState(PLAYER_1):GetPlayerOptionsString("ModsLevel_Current") + self:settextf("Mods: %s", mods) + end +} + -- Background Quad for Song banner t[#t+1] = Def.Quad{ InitCommand = function(self) @@ -60,16 +127,18 @@ t[#t+1] = Def.Quad{ } -- Song banner -t[#t+1] = Def.Banner{ +t[#t+1] = Def.Sprite { BeginCommand = function(self) - if song and not course then - self:LoadFromSong(song) - elseif course and not song then - self:LoadFromCourse(course) + if song then + local bnpath = song:GetBannerPath() + if not bnpath then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) end self:scaletofit(0,0,256,80) self:xy(SCREEN_CENTER_X,70) - end; + end } @@ -81,15 +150,11 @@ t[#t+1] = LoadFont("Common Normal")..{ self:maxwidth(((SCREEN_WIDTH/2 -5 -266/2)/0.6) - 10) self:diffuse(color(colorConfig:get_data().evaluation.BackgroundText)):diffusealpha(0.8) self:halign(0):valign(0) - end; + end, BeginCommand = function(self) - if GAMESTATE:IsCourseMode() then - self:settext(course:GetDisplayFullTitle()) - else - self:settext(song:GetDisplayMainTitle()) - end; - end; -}; + self:settext(song:GetDisplayMainTitle()) + end +} -- Artist and subtitles t[#t+1] = LoadFont("Common Normal")..{ @@ -99,105 +164,138 @@ t[#t+1] = LoadFont("Common Normal")..{ self:maxwidth(((SCREEN_WIDTH/2 -5 -266/2)/0.4) - 10) self:diffuse(color(colorConfig:get_data().evaluation.BackgroundText)):diffusealpha(0.8) self:halign(0):valign(0) - end; + end, BeginCommand = function(self) - if GAMESTATE:IsCourseMode() then - self:settext("//"..course:GetScripter()) + if song:GetDisplaySubTitle() ~= "" then + self:settextf("%s\n// %s",song:GetDisplaySubTitle(),song:GetDisplayArtist()) else - if song:GetDisplaySubTitle() ~= "" then - self:settextf("%s\n// %s",song:GetDisplaySubTitle(),song:GetDisplayArtist()) - else - self:settext("//"..song:GetDisplayArtist()) - end - end; - end; -}; + self:settext("//"..song:GetDisplayArtist()) + end + end +} -- Life graph and the stuff that goes with it local function GraphDisplay( pn ) - local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(pn) - local t = Def.ActorFrame { Def.GraphDisplay { InitCommand = function(self) self:Load("GraphDisplay") - end; + end, BeginCommand = function(self) local ss = SCREENMAN:GetTopScreen():GetStageStats() self:Set(ss,pss) - self:diffusealpha(0.5); + self:diffusealpha(0.5) self:GetChild("Line"):diffusealpha(0) self:y(55) end - }; + }, LoadFont("Common Large")..{ - Name = "Grade"; + Name = "Grade", InitCommand = function(self) self:xy(-frameWidth/2+35,55):zoom(0.7):maxwidth(70/0.8) - end; + end, BeginCommand=function(self) self:settext(THEME:GetString("Grade",ToEnumShortString(pss:GetHighScore():GetWifeGrade()))) - end; - }; + end, + SetJudgeCommand = function(self) + self:settext(THEME:GetString("Grade", ToEnumShortString(getWifeGradeTier(rescoredPercentage)))) + end, + ResetJudgeCommand = function(self) + self:playcommand("Begin") + end + }, LoadFont("Common Normal")..{ Font= "Common Normal", InitCommand= function(self) self:y(50):zoom(0.6) self:halign(0) - end; + end, BeginCommand=function(self) local wifeScore = pss:GetHighScore():GetWifeScore() - if GAMESTATE:GetNumPlayersEnabled() == 2 and pn == PLAYER_2 then - self:x(self:GetParent():GetChild("Grade"):GetX()+(math.min(self:GetParent():GetChild("Grade"):GetWidth()/0.8/2+15,35/0.8+15))*0.6) + self:x(self:GetParent():GetChild("Grade"):GetX()+(math.min(self:GetParent():GetChild("Grade"):GetWidth()/0.8/2+15,35/0.8+15))*0.6) + + if wifeScore > 0.99 then + self:settextf("%.4f%%",math.floor((wifeScore)*1000000)/10000) else - self:x(self:GetParent():GetChild("Grade"):GetX()+(math.min(self:GetParent():GetChild("Grade"):GetWidth()/0.8/2+15,35/0.8+15))*0.6) + self:settextf("%.2f%%",math.floor((wifeScore)*10000)/100) end - - self:settextf("%.2f%%",math.floor((wifeScore)*10000)/100) - end; - }; + end, + SetJudgeCommand = function(self, params) + if enabledCustomWindows then + self:settextf( + "%05.2f%% (%s)", + rescoredPercentage, + customWindow.name + ) + elseif params.Name == "PrevJudge" and judge >= 1 then + self:settextf( + "%05.2f%% (%s)", + rescoredPercentage, + "Wife J" .. judge + ) + elseif params.Name == "NextJudge" and judge <= 9 then + if judge == 9 then + self:settextf( + "%05.2f%% (%s)", + rescoredPercentage, + "Wife Justice" + ) + else + self:settextf( + "%05.2f%% (%s)", + rescoredPercentage, + "Wife J" .. judge + ) + end + end + end, + ResetJudgeCommand = function(self) + self:playcommand("Begin") + end + }, LoadFont("Common Normal")..{ InitCommand= function(self) self:y(63):zoom(0.4) self:halign(0) - end; + end, BeginCommand=function(self) -- Fix when maxwife is available to lua local grade,diff = getNearbyGrade(pn,pss:GetWifeScore()*getMaxNotes(pn)*2,pss:GetGrade()) diff = diff >= 0 and string.format("+%0.2f", diff) or string.format("%0.2f", diff) self:settextf("%s %s",THEME:GetString("Grade",ToEnumShortString(grade)),diff) - if GAMESTATE:GetNumPlayersEnabled() == 2 and pn == PLAYER_2 then - self:x(self:GetParent():GetChild("Grade"):GetX()+(math.min(self:GetParent():GetChild("Grade"):GetWidth()/0.8/2+15,35/0.8+15))*0.6) - else - self:x(self:GetParent():GetChild("Grade"):GetX()+(math.min(self:GetParent():GetChild("Grade"):GetWidth()/0.8/2+15,35/0.8+15))*0.6) + self:x(self:GetParent():GetChild("Grade"):GetX()+(math.min(self:GetParent():GetChild("Grade"):GetWidth()/0.8/2+15,35/0.8+15))*0.6) + end, + OffsetPlotModificationMessageCommand = function(self, params) + if params.Name == "ResetJudge" then + self:playcommand("Begin") + self:diffusealpha(1) + elseif params.Name == "NextJudge" or params.Name == "PrevJudge" then + self:diffusealpha(0) end - end; - }; + end + }, LoadFont("Common Normal")..{ InitCommand = function(self) self:xy(frameWidth/2-5,60-25+5):zoom(0.4):halign(1):valign(0):diffusealpha(0.7) - end; + end, BeginCommand=function(self) local text = "" text = string.format("Life: %.0f%%",pss:GetCurrentLife()*100) if pss:GetCurrentLife() == 0 then text = string.format("%s\n%.2fs Survived",text,pss:GetAliveSeconds()) end - if gameplay_pause_count > 0 then - text = string.format("%s\nPaused %d Time(s)",text,gameplay_pause_count) - end self:settext(text) - end; - }; - }; + end + } + } return t end @@ -206,7 +304,7 @@ local function ComboGraph( pn ) Def.ComboGraph { InitCommand = function(self) self:Load("ComboGraph"..ToEnumShortString(pn)) - end; + end, BeginCommand=function(self) local ss = SCREENMAN:GetTopScreen():GetStageStats() self:Set(ss,ss:GetPlayerStageStats(pn)) @@ -214,15 +312,18 @@ local function ComboGraph( pn ) } } return t -end; +end local function scoreBoard(pn) local hsTable = getScoreTable(pn, rate) local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(pn) - local steps = GAMESTATE:GetCurrentSteps(pn) local profile = PROFILEMAN:GetProfile(pn) - local index = getHighScoreIndex(hsTable, pss:GetHighScore()) - + local index + if hsTable == nil then + index = 1 + else + index = getHighScoreIndex(hsTable, pss:GetHighScore()) + end local recScore = getBestScore(pn, index, rate, true) local curScore = pss:GetHighScore() @@ -242,13 +343,17 @@ local function scoreBoard(pn) self:y(frameY+100) self:zoom(0.5) self:diffusealpha(0) - end; + end, OnCommand = function(self) self:RunCommandsOnChildren(function(self) self:queuecommand("Set") end) self:bouncy(0.3) self:y(frameY) self:zoom(1) self:diffusealpha(1) + end, + OffCommand = function(self) + self:bouncy(0.3) + self:y(500) end } @@ -268,10 +373,10 @@ local function scoreBoard(pn) self:zoomto(56,56) self:diffuse(color("#000000")) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) self:diffuse(getBorderColor()) - end; + end } t[#t+1] = Def.Quad{ @@ -290,13 +395,13 @@ local function scoreBoard(pn) InitCommand = function (self) self:xy(25+10-(frameWidth/2),5) self:visible(true) - self:LoadBackground(PROFILEMAN:GetAvatarPath(pn)); + self:LoadBackground(assetFolders.avatar .. findAvatar(PROFILEMAN:GetProfile(PLAYER_1):GetGUID())) self:zoomto(50,50) end } t[#t+1] = LoadFont("Common Normal")..{ - Name = "DisplayName"; + Name = "DisplayName", InitCommand = function(self) self:xy(69-frameWidth/2,9) self:zoom(0.6) @@ -308,7 +413,7 @@ local function scoreBoard(pn) text = pn == PLAYER_1 and "Player 1" or "Player 2" end self:settext(text) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -317,7 +422,7 @@ local function scoreBoard(pn) self:zoom(0.3) self:halign(0) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand = function(self) local text = "Lv.%d (%d/%d)" local level = getLevel(getProfileExp(pn)) @@ -329,7 +434,7 @@ local function scoreBoard(pn) end self:settextf(text,level, currentExp,nextExp) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -338,10 +443,34 @@ local function scoreBoard(pn) self:zoom(0.3) self:halign(0) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand = function(self) - self:settextf("Rating: %0.2f",profile:GetPlayerRating()) - end; + if DLMAN:IsLoggedIn() then + local rank = DLMAN:GetSkillsetRank("Overall") + local rating = DLMAN:GetSkillsetRating("Overall") + local localrating = profile:GetPlayerRating() + local rankDiff = GHETTOGAMESTATE:checkOnlineRank() + local finalStr = "" + if rankDiff < 0 then + finalStr = string.format("Rating: %0.2f (%0.2f #%d Online) %d rank change!", localrating, rating, rank, rankDiff) + self:settext(finalStr) + elseif rankDiff > 0 then + finalStr = string.format("Rating: %0.2f (%0.2f #%d Online) +%d rank change!", localrating, rating, rank, rankDiff) + self:settext(finalStr) + else + finalStr = string.format("Rating: %0.2f (%0.2f #%d Online)", localrating, rating, rank) + self:settext(finalStr) + end + self:AddAttribute(#"Rating:", {Length = 7, Zoom =0.3 ,Diffuse = getMSDColor(localrating)}) + self:AddAttribute(#"Rating: 00.00 ", {Length = -1, Zoom =0.3 ,Diffuse = getMSDColor(rating)}) + if rankDiff ~= 0 then + local tempStr = string.format("Rating: %0.2f (%0.2f #%d Online)", localrating, rating, rank) + self:AddAttribute(#tempStr+1, {Length = -1, Diffuse = color(colorConfig:get_data().evaluation.ScoreCardText)}) + end + else + self:settextf("Rating: %0.2f",profile:GetPlayerRating()) + end + end } @@ -351,28 +480,28 @@ local function scoreBoard(pn) self:zoom(0.3) self:halign(0) self:diffuse(getMainColor("positive")) - end; + end, SetCommand = function(self) self:settextf("+%d", getExpDiff(pn)) self:smooth(4) self:diffusealpha(0) self:addy(-5) - end; + end } - --Difficulty + --Diff & MSD t[#t+1] = LoadFont("Common Normal")..{ InitCommand = function(self) self:xy(frameWidth/2-5,5):zoom(0.5):halign(1):valign(0) self:glowshift():effectcolor1(color("1,1,1,0.05")):effectcolor2(color("1,1,1,0")):effectperiod(2) - end; + end, SetCommand=function(self) local diff = steps:GetDifficulty() local stype = ToEnumShortString(steps:GetStepsType()):gsub("%_"," ") local meter = steps:GetMSD(getCurRateValue(),1) - meter = meter == 0 and steps:GetMeter() or math.floor(meter) + meter = meter == 0 and steps:GetMeter() or meter local difftext if diff == 'Difficulty_Edit' and IsUsingWideScreen() then @@ -383,33 +512,29 @@ local function scoreBoard(pn) end if IsUsingWideScreen() then - self:settext(stype.." "..difftext.." "..meter) + self:settextf("%s %s %5.2f", stype, difftext, meter) + self:diffuse(getDifficultyColor(GetCustomDifficulty(steps:GetStepsType(),steps:GetDifficulty()))) + self:AddAttribute(#stype + #difftext + 2, {Length = -1, Diffuse = byMSD(meter)}) else - self:settext(difftext.." "..meter) + self:settextf("%s %5.2f", difftext, meter) + self:diffuse(getDifficultyColor(GetCustomDifficulty(steps:GetStepsType(),steps:GetDifficulty()))) + self:AddAttribute(#difftext + 1, {Length = -1, Diffuse = byMSD(meter)}) end - - self:diffuse(getDifficultyColor(GetCustomDifficulty(steps:GetStepsType(),steps:GetDifficulty()))) - end } - -- Notecount + -- SSR t[#t+1] = LoadFont("Common Normal")..{ InitCommand = function(self) - self:xy(frameWidth/2-5,19):zoom(0.4):halign(1):valign(0):diffusealpha(0.7) - end; + self:xy(frameWidth/2-5,19):zoom(0.4):halign(1):valign(0) + end, SetCommand=function(self) - local notes = steps:GetRadarValues(pn):GetValue("RadarCategory_Notes") - self:settextf("%d Notes",notes) - - if GAMESTATE:GetNumPlayersEnabled() == 1 and GAMESTATE:IsPlayerEnabled(PLAYER_2)then - self:x(-(SCREEN_CENTER_X*1.65)+(SCREEN_CENTER_X*0.35)+WideScale(get43size(140),140)-5) - end - - self:diffuse(Saturation(getDifficultyColor(GetCustomDifficulty(steps:GetStepsType(),steps:GetDifficulty())),0.3)) - end; - }; + local meter = curScore:GetSkillsetSSR("Overall") + self:settextf("Score Specific Rating %5.2f", meter) + self:AddAttribute(#"Score Specific Rating", {Length = -1, Diffuse = byMSD(meter)}) + end + } --ClearType t[#t+1] = LoadFont("Common Normal")..{ @@ -417,9 +542,18 @@ local function scoreBoard(pn) self:xy(-frameWidth/2+5,107) self:zoom(0.35) self:halign(0):valign(1) - self:settext(THEME:GetString("ScreenEvaluation","CategoryClearType")) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardCategoryText)) - end; + self:playcommand("Set") + end, + SetCommand = function(self) + self:settext(THEME:GetString("ScreenEvaluation","CategoryClearType")) + end, + SetJudgeCommand = function(self) + self:settextf("%s (J%d)", THEME:GetString("ScreenEvaluation", "CategoryClearType"), GetTimingDifficulty()) + end, + ResetJudgeCommand = function(self) + self:playcommand("Set") + end } t[#t+1] = Def.Quad{ @@ -436,11 +570,11 @@ local function scoreBoard(pn) self:xy(frameWidth/2-50,107) self:zoom(0.5) self:halign(1):valign(1) - end; + end, SetCommand = function(self) self:settext(getClearTypeText(clearType)) self:diffuse(getClearTypeColor(clearType)) - end; + end } @@ -449,13 +583,13 @@ local function scoreBoard(pn) self:xy(frameWidth/2-50,113) self:zoom(0.35) self:halign(1):valign(0) - end; + end, SetCommand = function(self) local clearType = getHighestClearType(pn,steps,hsTable,index) self:settext(getClearTypeText(clearType)) self:diffuse(getClearTypeColor(clearType)) self:diffusealpha(0.5) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -463,7 +597,7 @@ local function scoreBoard(pn) self:xy(frameWidth/2-40,106) self:zoom(0.30) self:valign(1) - end; + end, SetCommand = function(self) local recCTLevel = getClearTypeLevel(getHighestClearType(pn,steps,hsTable,index)) local curCTLevel = getClearTypeLevel(clearType) @@ -477,7 +611,7 @@ local function scoreBoard(pn) self:settext("-") self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) end - end; + end } -- Score @@ -489,8 +623,17 @@ local function scoreBoard(pn) self:zoom(0.35) self:halign(0):valign(1) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardCategoryText)) + self:playcommand("Set") + end, + SetCommand = function(self) self:settextf("%s - %s",THEME:GetString("ScreenEvaluation","CategoryScore"),getScoreTypeText(1)) - end; + end, + SetJudgeCommand = function(self) + self:settextf("%s - %s J%d", THEME:GetString("ScreenEvaluation", "CategoryScore"), getScoreTypeText(1), GetTimingDifficulty()) + end, + ResetJudgeCommand = function(self) + self:playcommand("Set") + end } t[#t+1] = Def.Quad{ @@ -508,7 +651,7 @@ local function scoreBoard(pn) self:zoom(0.5) self:halign(1):valign(1) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand = function(self) local notes = steps:GetRadarValues(pn):GetValue("RadarCategory_Notes") local curScoreValue = getScore(curScore, steps, false) @@ -516,7 +659,7 @@ local function scoreBoard(pn) local maxScoreValue = notes * 2 local percentText = string.format("%05.2f%%",math.floor(curScorePercent*10000)/100) self:settextf("%s (%d/%d)",percentText,curScoreValue,maxScoreValue) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -525,14 +668,14 @@ local function scoreBoard(pn) self:zoom(0.35) self:halign(1):valign(0) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)):diffusealpha(0.3) - end; + end, SetCommand = function(self) local recScoreValue = getScore(recScore, steps, true) local maxScore = getMaxScore(pn) local percentText = string.format("%05.2f%%",math.floor(recScoreValue*10000)/100) self:settextf("%s (%0.0f/%d)",percentText,recScoreValue*maxScore,maxScore) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -540,7 +683,7 @@ local function scoreBoard(pn) self:xy(frameWidth/2-40,136) self:zoom(0.30) self:valign(1) - end; + end, SetCommand = function(self) local curScoreValue = getScore(curScore, steps, false) local recScoreValue = getScore(recScore, steps, false) @@ -556,7 +699,7 @@ local function scoreBoard(pn) self:settext("-") self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) end - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -565,7 +708,7 @@ local function scoreBoard(pn) self:zoom(0.30) self:valign(1) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand = function(self) local curScoreValue = getScore(curScore, steps, false) local recScoreValue = getScore(recScore, steps, false) @@ -574,9 +717,9 @@ local function scoreBoard(pn) local extra = "" if diff >= 0 then extra = "+" - end; + end self:settextf("%s%0.2f",extra,diff) - end; + end } -- Misscount @@ -587,8 +730,11 @@ local function scoreBoard(pn) self:zoom(0.35) self:halign(0):valign(1) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardCategoryText)) + self:playcommand("Set") + end, + SetCommand = function(self) self:settext(THEME:GetString("ScreenEvaluation","CategoryMissCount")) - end; + end } t[#t+1] = Def.Quad{ @@ -606,11 +752,11 @@ local function scoreBoard(pn) self:zoom(0.5) self:halign(1):valign(1) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand = function(self) local missCount = getScoreMissCount(curScore) self:settext(missCount) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -619,7 +765,7 @@ local function scoreBoard(pn) self:zoom(0.35) self:halign(1):valign(0) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)):diffusealpha(0.3) - end; + end, SetCommand = function(self) local score = getBestMissCount(pn,index, rate) local missCount = getScoreMissCount(score) @@ -629,7 +775,7 @@ local function scoreBoard(pn) else self:settext("-") end - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -637,7 +783,7 @@ local function scoreBoard(pn) self:xy(frameWidth/2-40,166) self:zoom(0.30) self:valign(1) - end; + end, SetCommand = function(self) local score = getBestMissCount(pn,index, rate) @@ -660,8 +806,8 @@ local function scoreBoard(pn) else self:settext("-") self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; - end; + end + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -670,7 +816,7 @@ local function scoreBoard(pn) self:zoom(0.30) self:valign(1) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand = function(self) local score = getBestMissCount(pn,index, rate) local recMissCount = getScoreMissCount(score) @@ -682,12 +828,12 @@ local function scoreBoard(pn) diff = curMissCount - recMissCount if diff >= 0 then extra = "+" - end; + end self:settext(extra..diff) else self:settext("+"..curMissCount) - end; - end; + end + end } -- Tap judgments @@ -699,7 +845,7 @@ local function scoreBoard(pn) self:halign(0):valign(1) self:settext(THEME:GetString("ScreenEvaluation","CategoryJudgment")) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardCategoryText)) - end; + end } t[#t+1] = Def.Quad{ @@ -718,14 +864,14 @@ local function scoreBoard(pn) self:zoom(0.4) self:settext(getJudgeStrings(v)) self:diffuse(TapNoteScoreToColor(v)) - end; - }; + end + } t[#t+1] = LoadFont("Common Normal")..{ InitCommand= function(self) self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*k),225) self:zoom(0.35) - end; + end, SetCommand=function(self) local percent = pss:GetPercentageOfTaps(v) if tostring(percent) == tostring(0/0) then @@ -733,6 +879,16 @@ local function scoreBoard(pn) end self:diffuse(lerp_color(percent,Saturation(TapNoteScoreToColor(v),0.1),Saturation(TapNoteScoreToColor(v),0.4))) self:settext(pss:GetTapNoteScores(v)) + end, + SetJudgeCommand = function(self) + if enabledCustomWindows then + self:settext(getRescoredCustomJudge(dvt, customWindow.judgeWindows, k)) + else + self:settext(getRescoredJudge(dvt, judge, k)) + end + end, + ResetJudgeCommand = function(self) + self:playcommand("Set") end } @@ -740,7 +896,7 @@ local function scoreBoard(pn) InitCommand= function(self) self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*k),235) self:zoom(0.30) - end; + end, SetCommand=function(self) local percent = pss:GetPercentageOfTaps(v) if tostring(percent) == tostring(0/0) then @@ -748,6 +904,16 @@ local function scoreBoard(pn) end self:diffuse(lerp_color(percent,Saturation(TapNoteScoreToColor(v),0.1),Saturation(TapNoteScoreToColor(v),0.4))) self:settextf("(%.2f%%)",math.floor(percent*10000)/100) + end, + SetJudgeCommand = function(self) + if enabledCustomWindows then + self:settextf("(%.2f%%)", getRescoredCustomJudge(dvt, customWindow.judgeWindows, k) / totalTaps * 100) + else + self:settextf("(%.2f%%)", getRescoredJudge(dvt, judge, k) / totalTaps * 100) + end + end, + ResetJudgeCommand = function(self) + self:playcommand("Set") end } end @@ -755,7 +921,7 @@ local function scoreBoard(pn) for k,v in ipairs(hjudges) do t[#t+1] = LoadFont("Common Normal")..{ InitCommand= function(self) - self:xy(((-(frameWidth+frameWidth/4)/2)+((frameWidth+frameWidth/4)/5)*k),260) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*k),260) self:zoom(0.4) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) @@ -764,15 +930,15 @@ local function scoreBoard(pn) text = "Hold "..text end self:settext(text) - end; - }; + end + } t[#t+1] = LoadFont("Common Normal")..{ InitCommand= function(self) - self:xy(((-(frameWidth+frameWidth/4)/2)+((frameWidth+frameWidth/4)/5)*k),275) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*k),275) self:zoom(0.35) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand=function(self) local percent = pss:GetHoldNoteScores(v)/(pss:GetRadarPossible():GetValue('RadarCategory_Holds')+pss:GetRadarPossible():GetValue('RadarCategory_Rolls')) if tostring(percent) == tostring(0/0) then @@ -785,10 +951,10 @@ local function scoreBoard(pn) t[#t+1] = LoadFont("Common Normal")..{ InitCommand= function(self) - self:xy(((-(frameWidth+frameWidth/4)/2)+((frameWidth+frameWidth/4)/5)*k),285) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*k),285) self:zoom(0.30) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand=function(self) local percent = pss:GetHoldNoteScores(v)/(pss:GetRadarPossible():GetValue('RadarCategory_Holds')+pss:GetRadarPossible():GetValue('RadarCategory_Rolls')) if tostring(percent) == tostring(0/0) then @@ -802,19 +968,19 @@ local function scoreBoard(pn) t[#t+1] = LoadFont("Common Normal")..{ InitCommand= function(self) - self:xy(((-(frameWidth+frameWidth/4)/2)+((frameWidth+frameWidth/4)/5)*4),260) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*4),260) self:zoom(0.4) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) self:settext("Mines Hit") - end; - }; + end + } t[#t+1] = LoadFont("Common Normal")..{ InitCommand= function(self) - self:xy(((-(frameWidth+frameWidth/4)/2)+((frameWidth+frameWidth/4)/5)*4),275) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*4),275) self:zoom(0.35) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand=function(self) local percent = pss:GetTapNoteScores('TapNoteScore_HitMine')/(pss:GetRadarPossible():GetValue('RadarCategory_Mines'))*100 if tostring(percent) == tostring(0/0) then @@ -827,10 +993,10 @@ local function scoreBoard(pn) t[#t+1] = LoadFont("Common Normal")..{ InitCommand= function(self) - self:xy(((-(frameWidth+frameWidth/4)/2)+((frameWidth+frameWidth/4)/5)*4),285) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*4),285) self:zoom(0.30) self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) - end; + end, SetCommand=function(self) local percent = pss:GetTapNoteScores('TapNoteScore_HitMine')/(pss:GetRadarPossible():GetValue('RadarCategory_Mines'))*100 if tostring(percent) == tostring(0/0) then @@ -841,34 +1007,1112 @@ local function scoreBoard(pn) end } + -- stolen from Til Death without any shame + local tracks = pss:GetTrackVector() + local devianceTable = pss:GetOffsetVector() + local cbl = 0 + local cbr = 0 + + local tst = ms.JudgeScalers + local tso = tst[judge] + if enabledCustomWindows then + tso = 1 + end + local ncol = GAMESTATE:GetCurrentSteps(PLAYER_1):GetNumColumns() - 1 + for i = 1, #devianceTable do + if tracks[i] then + if math.abs(devianceTable[i]) > tso * 90 then + if tracks[i] <= math.floor(ncol/2) then + cbl = cbl + 1 + else + cbr = cbr + 1 + end + end + end + end + local statCategory = { + "Mean", + "Mean(Abs)", + "Sd", + "Left cbs", + "Right cbs" + } + local statInfo = { + wifeMean(devianceTable), + wifeAbsMean(devianceTable), + wifeSd(devianceTable), + cbl, + cbr + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand= function(self) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*5),260) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) + self:settext("Mean") + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand= function(self) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*5),275) + self:zoom(0.35) + self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) + end, + SetCommand=function(self) + self:diffuse(Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.1),Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.4)) + self:settextf("%.2fms", statInfo[1]) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand= function(self) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*5),285) + self:zoom(0.25) + self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) + end, + SetCommand=function(self) + self:diffuse(Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.1),Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.4)) + self:settextf("%.2fms (abs)", statInfo[2]) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand= function(self) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*5),292) + self:zoom(0.25) + self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) + end, + SetCommand=function(self) + self:diffuse(Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.1),Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.4)) + self:settextf("%.2fms (std dev)", statInfo[3]) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand= function(self) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*6),260) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) + self:settext("CBs") + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand= function(self) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*6),275) + self:zoom(0.3) + self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) + end, + SetCommand=function(self) + self:diffuse(Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.1),Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.4)) + self:settextf("Left: %d", statInfo[4]) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand= function(self) + self:xy(((-(frameWidth+frameWidth/6)/2)+((frameWidth+frameWidth/6)/7)*6),285) + self:zoom(0.30) + self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardText)) + end, + SetCommand=function(self) + self:diffuse(Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.1),Saturation(color(colorConfig:get_data().evaluation.ScoreCardText),0.4)) + self:settextf("Right: %d", statInfo[5]) + end + } + return t -end; +end for _,pn in pairs(GAMESTATE:GetEnabledPlayers()) do t[#t+1] = scoreBoard(pn) end -if GAMESTATE:GetNumPlayersEnabled() == 1 then - t[#t+1] = LoadActor(THEME:GetPathG("","OffsetGraph"))..{ - InitCommand = function(self, params) - self:xy(SCREEN_CENTER_X*3/2-frameWidth/2, 200) - - local pn = GAMESTATE:GetEnabledPlayers()[1] - local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(pn) - local steps = GAMESTATE:GetCurrentSteps(pn) - - self:RunCommandsOnChildren(function(self) - local params = {width = frameWidth, - height = 150, - song = song, - steps = steps, - noterow = pss:GetNoteRowVector(), - offset = pss:GetOffsetVector()} - self:playcommand("Update", params) end - ) - end; + +local player = GAMESTATE:GetEnabledPlayers()[1] +local song = STATSMAN:GetCurStageStats():GetPlayedSongs()[1] +local profile = GetPlayerOrMachineProfile(player) +local hsTable = getScoreTable(player, getCurRate()) +local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(player) +local score = pss:GetHighScore() +local scoreIndex = getHighScoreIndex(hsTable, score) +local newScoreboardInitialLocalIndex = scoreIndex +local newScoreboardInitialLocalIndex2 = scoreIndex -- dont ask about this please i dont want to explain myself + +local lbActor +local offsetScoreID +local offsetIndex +local offsetisLocal +local currentCountry = "Global" +local scoresPerPage = 5 +local maxPages = math.ceil(#hsTable/scoresPerPage) +local curPage = 1 +local alreadyPulled = false + +local function updateLeaderBoardForCurrentChart() + alreadyPulled = true + if steps then + DLMAN:RequestChartLeaderBoardFromOnline( + steps:GetChartKey(), + function(leaderboard) + lbActor:queuecommand("SetFromLeaderboard", leaderboard) + end + ) + else + lbActor:queuecommand("SetFromLeaderboard", {}) + end +end + +local function movePage(n) + if maxPages <= 1 then + return + end + + if n > 0 then + curPage = ((curPage+n-1) % maxPages + 1) + else + curPage = ((curPage+n+maxPages-1) % maxPages+1) + end + MESSAGEMAN:Broadcast("UpdateList") +end + +local function scoreboardInput(event) + if event.type == "InputEventType_FirstPress" then + if maxPages <= 1 then + return + end + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + end + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + end + if event.button == "MenuLeft" then + movePage(-1) + end + + if event.button == "MenuRight" then + movePage(1) + end + + end +end + +-- this is the dynamic scoreboard for all the cool scores +-- bad name dont ask (do ask) +local function boardOfScores() + local frameWidth = SCREEN_CENTER_X-WideScale(get43size(40),40) + local frameHeight = 150 + local frameX = SCREEN_WIDTH - frameWidth - WideScale(get43size(40),40)/2 + local frameY = 154 + local spacing = 1 + local isLocal = true + local topScoresOnly = true + local loggedIn = DLMAN:IsLoggedIn() + + local scoreItemWidth = frameWidth / 1.7 + local scoreItemHeight = frameHeight / 8 + local scoreItemX = frameWidth / 6 + 3 + 2 -- button width + divider width + spacing width + local scoreItemY = 8 + local scoreItemSpacing = spacing + + local t = Def.ActorFrame { + Name = "ScoreBoardContainer", + InitCommand = function(self) + lbActor = self + end, + OnCommand = function(self) + self:addy(-25) + self:bouncy(0.2) + self:addy(25) + SCREENMAN:GetTopScreen():AddInputCallback(scoreboardInput) + self:queuecommand("UpdateScores") + end, + OffCommand = function(self) + self:stoptweening() + self:bouncy(0.2) + self:x(SCREEN_CENTER_X*3/2-frameWidth/2 + 100) + self:diffusealpha(0) + end, + UpdateScoresMessageCommand = function(self, params) + if isLocal then + scoreList = getScoreTable(player, getCurRate()) + else + scoreList = DLMAN:GetChartLeaderBoard(steps:GetChartKey(), currentCountry) + if #scoreList == 0 and not alreadyPulled then + updateLeaderBoardForCurrentChart() + end + end + curPage = 1 + if scoreList ~= nil then + maxPages = math.ceil(#scoreList / scoresPerPage) + else + maxPages = 1 + end + if isLocal or #scoreList ~= 0 then + self:queuecommand("Set") + elseif #scoreList == 0 then + self:queuecommand("ListEmpty") + end + + end, + SetFromLeaderboardCommand = function(self, leaderboard) + self:queuecommand("UpdateScores") + end, + + -- the quad for the background of the container + Def.Quad { + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")):diffusealpha(0.8) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() then + movePage(1) + end + end + }, + + -- the sneaky quad for the divider between this container and the one below + Def.Quad { + InitCommand = function(self) + self:y(frameHeight - 1) + self:zoomto(frameWidth,1) + self:halign(0):valign(0) + self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardDivider)):diffusealpha(0.8) + end + }, + + -- the quad for other divider just separating stuff + Def.Quad { + InitCommand = function(self) + self:xy(frameWidth/6, 5) + self:zoomto(2,frameHeight - 10) + self:halign(0):valign(0) + self:diffuse(color(colorConfig:get_data().evaluation.ScoreCardDivider)):diffusealpha(0.8) + end + }, + + -- Page info text + LoadFont("Common Normal") .. { + InitCommand = function(self) + --self:settext("Showing ? - ? of ? scores") + self:zoom(0.35) + self:xy((frameWidth - (frameWidth/6))/2 + frameWidth/6, frameHeight - 25) + end, + SetCommand = function(self) + self:settextf("Showing %d - %d of %d scores", (curPage-1) * scoresPerPage + 1, math.min((curPage) * scoresPerPage,#scoreList), #scoreList) + end, + UpdateListMessageCommand = function(self) + self:playcommand("Set") + end, + ListEmptyCommand = function(self) + self:settext("Showing 0 - 0 of 0 scores") + end + }, + + -- Sort info text + LoadFont("Common Normal") .. { + InitCommand = function(self) + --self:settext("Placeholder.") + self:zoom(0.35) + self:xy((frameWidth - (frameWidth/6))/2 + frameWidth/6, frameHeight - 15) + end, + SetCommand = function(self) + if isLocal then + self:settext("Highest local scores for this rate") + else + local allRates = not DLMAN:GetCurrentRateFilter() + local allScores = not DLMAN:GetTopScoresOnlyFilter() + if allRates and allScores then + self:settext("All online scores for all rates") + elseif allRates and not allScores then + self:settext("Highest online scores for all rates") + elseif not allRates and allScores then + self:settext("All online scores for this rate") -- this is actually no different from the one below + else + self:settext("Highest online scores for this rate") -- but i wanted to make the distinction + end + end + end, + ListEmptyCommand = function(self) + self:settext("No scores found") + end + }, + + -- Basic info text + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:settext("Click for Offset Plot") + self:zoom(0.2) + self:valign(0) + self:xy(scoreItemX + scoreItemWidth/2, (scoreItemHeight + scoreItemSpacing + 1) * scoresPerPage + scoreItemY) + self:diffusealpha(0) + end, + UpdateListMessageCommand = function(self) + local scoresOnThisPage = math.abs((curPage-1) * scoresPerPage + 1 - math.min((curPage) * scoresPerPage,#scoreList)) + if #scoreList == 0 then + self:diffusealpha(0) + return + end + self:stoptweening() + self:diffusealpha(0) + self:y((scoreItemHeight) * (scoresOnThisPage+1) + (scoreItemSpacing*scoresOnThisPage) + scoreItemY - 8) + self:sleep((scoresOnThisPage+1)*0.03) + self:diffusealpha(1) + self:easeOut(0.5) + self:y((scoreItemHeight) * (scoresOnThisPage+1) + (scoreItemSpacing*scoresOnThisPage) + scoreItemY + 2) + end, + UpdateScoresCommand = function(self) + self:playcommand("UpdateList") + end, + ListEmptyCommand = function(self) + self:playcommand("UpdateList") + end + }, + + -- Basic info text 2 + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:settext("Click for Replay") + self:zoom(0.2) + self:valign(0) + self:diffusealpha(0) + self:xy(scoreItemX + scoreItemWidth + 10 + (frameWidth - scoreItemWidth - scoreItemX - 20)/2, (scoreItemHeight + scoreItemSpacing + 1) * scoresPerPage + scoreItemY) + end, + UpdateListMessageCommand = function(self) + local scoresOnThisPage = math.abs((curPage-1) * scoresPerPage + 1 - math.min((curPage) * scoresPerPage,#scoreList)) + if #scoreList == 0 then + self:diffusealpha(0) + return + end + self:stoptweening() + self:diffusealpha(0) + self:y((scoreItemHeight) * (scoresOnThisPage+1) + (scoreItemSpacing*scoresOnThisPage) + scoreItemY - 8) + self:sleep((scoresOnThisPage+1)*0.03) + self:diffusealpha(1) + self:easeOut(0.5) + self:y((scoreItemHeight) * (scoresOnThisPage+1) + (scoreItemSpacing*scoresOnThisPage) + scoreItemY + 2) + end, + UpdateScoresCommand = function(self) + self:playcommand("UpdateList") + end, + ListEmptyCommand = function(self) + self:playcommand("UpdateList") + end + }, + + -- Local scores button + quadButton(6) .. { + InitCommand = function(self) + self:xy(3, 8) + self:zoomto(frameWidth/6 - 6, frameHeight / 8) + self:halign(0):valign(0) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + if not loggedIn then + self:diffusealpha(0.05) + return + end + if not isLocal then + self:diffusealpha(0.1) + else + self:diffusealpha(0.4) + end + end, + TopPressedCommand = function(self) + if not isLocal and loggedIn then + isLocal = true + self:GetParent():queuecommand("UpdateScores") + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:settext("Local") + self:zoom(0.45) + self:xy(3, 8) + self:addx((frameWidth/6 - 6)/2) + self:addy((frameHeight / 8)/2) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if not loggedIn then + self:diffusealpha(0.05) + return + else + self:diffusealpha(1) + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + + -- Online scores button + quadButton(6) .. { + InitCommand = function(self) + self:xy(3, 8 + (frameHeight / 8) + spacing) + self:zoomto(frameWidth/6 - 6, frameHeight / 8) + self:halign(0):valign(0) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if not loggedIn then + self:diffusealpha(0.05) + return + end + if isLocal then + self:diffusealpha(0.1) + else + self:diffusealpha(0.4) + end + end, + TopPressedCommand = function(self) + if isLocal and loggedIn then + isLocal = false + self:GetParent():queuecommand("UpdateScores") + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:settext("Online") + self:zoom(0.45) + self:xy(3, 8 + (frameHeight / 8) + spacing) + self:addx((frameWidth/6 - 6)/2) + self:addy((frameHeight / 8)/2) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if not loggedIn then + self:diffusealpha(0.05) + return + else + self:diffusealpha(1) + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + + -- Current rate button + quadButton(6) .. { + InitCommand = function(self) + self:xy(3, frameHeight - 8 - (frameHeight/8/2) * 2 - spacing) + self:zoomto(frameWidth/6 - 6, frameHeight / 8 / 2) + self:halign(0):valign(0) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if isLocal then + self:diffusealpha(0.05) + else + if DLMAN:GetCurrentRateFilter() then + self:diffusealpha(0.4) + else + self:diffusealpha(0.1) + end + end + end, + TopPressedCommand = function(self) + if not isLocal and loggedIn then + if not DLMAN:GetCurrentRateFilter() then + DLMAN:ToggleRateFilter() + self:GetParent():queuecommand("UpdateScores") + end + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:settext("Current Rate") + self:zoom(0.25) + self:xy(3, frameHeight - 8 - (frameHeight/8/2) * 2 - spacing) + self:addx((frameWidth/6 - 6)/2) + self:addy((frameHeight / 8 / 2)/2) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if isLocal then + self:diffusealpha(0.05) + else + self:diffusealpha(1) + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + + -- All rates button + quadButton(6) .. { + InitCommand = function(self) + self:xy(3, frameHeight - 8 - (frameHeight/8/2)) + self:zoomto(frameWidth/6 - 6, frameHeight / 8 / 2) + self:halign(0):valign(0) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if isLocal then + self:diffusealpha(0.05) + else + if DLMAN:GetCurrentRateFilter() then + self:diffusealpha(0.1) + else + self:diffusealpha(0.4) + end + end + end, + TopPressedCommand = function(self) + if not isLocal and loggedIn then + if DLMAN:GetCurrentRateFilter() then + DLMAN:ToggleRateFilter() + self:GetParent():queuecommand("UpdateScores") + end + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:settext("All Rates") + self:zoom(0.25) + self:xy(3, frameHeight - 8 - (frameHeight/8/2)) + self:addx((frameWidth/6 - 6)/2) + self:addy((frameHeight / 8 / 2)/2) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if isLocal then + self:diffusealpha(0.05) + else + self:diffusealpha(1) + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + + -- Top Scores button + quadButton(6) .. { + InitCommand = function(self) + self:xy(3, frameHeight - 8 - (frameHeight/8/2)*3 - spacing*3) + self:zoomto(frameWidth/6 - 6, frameHeight / 8 / 2) + self:halign(0):valign(0) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if isLocal then + self:diffusealpha(0.05) + else + if DLMAN:GetTopScoresOnlyFilter() then + self:diffusealpha(0.4) + else + self:diffusealpha(0.1) + end + end + end, + TopPressedCommand = function(self) + if not isLocal and loggedIn then + if not DLMAN:GetTopScoresOnlyFilter() then + DLMAN:ToggleTopScoresOnlyFilter() + self:GetParent():queuecommand("UpdateScores") + end + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:settext("Top Scores") + self:zoom(0.25) + self:xy(3, frameHeight - 8 - (frameHeight/8/2)*3 - spacing*3) + self:addx((frameWidth/6 - 6)/2) + self:addy((frameHeight / 8 / 2)/2) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if isLocal then + self:diffusealpha(0.05) + else + self:diffusealpha(1) + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + + -- All Scores button + quadButton(6) .. { + InitCommand = function(self) + self:xy(3, frameHeight - 8 - (frameHeight/8/2)*4 - spacing*4) + self:zoomto(frameWidth/6 - 6, frameHeight / 8 / 2) + self:halign(0):valign(0) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if isLocal then + self:diffusealpha(0.05) + else + if DLMAN:GetTopScoresOnlyFilter() then + self:diffusealpha(0.1) + else + self:diffusealpha(0.4) + end + end + end, + TopPressedCommand = function(self) + if not isLocal and loggedIn then + if DLMAN:GetTopScoresOnlyFilter() then + DLMAN:ToggleTopScoresOnlyFilter() + self:GetParent():queuecommand("UpdateScores") + end + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:settext("All Scores") + self:zoom(0.25) + self:xy(3, frameHeight - 8 - (frameHeight/8/2)*4 - spacing*4) + self:addx((frameWidth/6 - 6)/2) + self:addy((frameHeight / 8 / 2)/2) + self:diffusealpha(0.05) + end, + SetCommand = function(self) + self:linear(0.1) + if isLocal then + self:diffusealpha(0.05) + else + self:diffusealpha(1) + end + end, + ListEmptyCommand = function(self) + self:queuecommand("Set") + end + } } + + -- individual items for the score buttons + local function scoreItem(i) + local scoreIndex = (curPage - 1) * scoresPerPage + i + + local d = Def.ActorFrame { + InitCommand = function(self) + self:xy(scoreItemX, scoreItemY + (i-1) * (scoreItemHeight + scoreItemSpacing)) + self:diffusealpha(0) + end, + ShowCommand = function(self) + self:y(scoreItemY + (i-1)*(scoreItemHeight + scoreItemSpacing)-10) + self:diffusealpha(0) + self:finishtweening() + self:sleep(math.max(0.01, (i-1)*0.03)) + self:easeOut(1) + self:y(scoreItemY + (i-1)*(scoreItemHeight + scoreItemSpacing)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + self:y(SCREEN_HEIGHT*10) + end, + UpdateListMessageCommand = function(self) + self:playcommand("UpdateScores") + end, + UpdateScoresMessageCommand = function(self) + scoreIndex = (curPage - 1) * scoresPerPage + i + if scoreList[scoreIndex] ~= nil then + self:playcommand("Show") + else + self:playcommand("Hide") + end + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + end + } + + -- BG+Button for score item + d[#d+1] = quadButton(6) .. { + InitCommand = function(self) + self:halign(0):valign(0) + self:diffusealpha(0.1) + self:zoomto(scoreItemWidth, scoreItemHeight) + end, + SetCommand = function(self) + if scoreList[scoreIndex] ~= nil and ((scoreIndex == offsetIndex and offsetisLocal and isLocal) or (scoreList[scoreIndex]:GetScoreid() == offsetScoreID and not offsetisLocal and not isLocal) or (isLocal and offsetIndex == nil and scoreIndex == newScoreboardInitialLocalIndex)) then + self:diffusealpha(0.3) + else + self:diffusealpha(0.1) + end + end, + TopPressedCommand = function(self) + if scoreList[scoreIndex] == nil or not scoreList[scoreIndex]:HasReplayData() then + return + end + newScoreboardInitialLocalIndex = 0 + offsetIndex = scoreIndex + offsetScoreID = scoreList[scoreIndex]:GetScoreid() + offsetisLocal = isLocal + MESSAGEMAN:Broadcast("ShowScoreOffset") + self:finishtweening() + self:diffusealpha(0.3) + self:GetParent():GetParent():playcommand("Set") + end + } + + -- symbol indicating that this is the score you just set + d[#d+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "CurrentScoreIndicator", + InitCommand = function(self) + self:zoom(0.10) + self:diffusealpha(0.8) + self:rotationz(90) + self:diffuse(color("#aaaaff")) + self:diffusealpha(0) + self:xy(3, scoreItemHeight/4) + end, + SetCommand = function(self) + if scoreList[scoreIndex] == nil then + return + end + if (isLocal == true and scoreIndex == newScoreboardInitialLocalIndex2) then + self:linear(0.1) + self:diffusealpha(1) + else + self:diffusealpha(0) + end + end + } + + -- grade + d[#d+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(22,scoreItemHeight/4) + self:zoom(0.3) + end, + SetCommand = function(self) + if scoreList[scoreIndex] == nil then + return + end + local grade = scoreList[scoreIndex]:GetWifeGrade() + self:settext(THEME:GetString("Grade",ToEnumShortString(grade))) + self:diffuse(getGradeColor(grade)) + end + } + -- cleartype + d[#d+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(22,scoreItemHeight/4 * 3) + self:zoom(0.3) + self:maxwidth(135) + end, + SetCommand = function(self) + if scoreList[scoreIndex] == nil then + return + end + local clearType = getClearType(PLAYER_1, steps, scoreList[scoreIndex]) + self:settext(getClearTypeShortText(clearType)) + self:diffuse(getClearTypeColor(clearType)) + end + } + -- score percent and judgments + d[#d+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(45,scoreItemHeight/4) + self:halign(0) + self:zoom(0.3) + end, + SetCommand = function(self) + if scoreList[scoreIndex] == nil then + return + end + local score = scoreList[scoreIndex]:GetWifeScore() + local w1 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W1") + local w2 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W2") + local w3 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W3") + local w4 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W4") + local w5 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W5") + local miss = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_Miss") + if score >= 0.99 then + self:settextf("%0.4f%% | %d - %d - %d - %d - %d - %d",math.floor(score*1000000)/10000, w1, w2, w3, w4, w5, miss) + self:AddAttribute(11, {Length = #tostring(w1), Diffuse = byJudgment("TapNoteScore_W1")}) + self:AddAttribute(14 + #tostring(w1), {Length = #tostring(w2), Diffuse = byJudgment("TapNoteScore_W2")}) + self:AddAttribute(17 + #tostring(w1) + #tostring(w2), {Length = #tostring(w3), Diffuse = byJudgment("TapNoteScore_W3")}) + self:AddAttribute(20 + #tostring(w1) + #tostring(w2) + #tostring(w3), {Length = #tostring(w4), Diffuse = byJudgment("TapNoteScore_W4")}) + self:AddAttribute(23 + #tostring(w1) + #tostring(w2) + #tostring(w3) + #tostring(w4), {Length = #tostring(w5), Diffuse = byJudgment("TapNoteScore_W5")}) + self:AddAttribute(26 + #tostring(w1) + #tostring(w2) + #tostring(w3) + #tostring(w4) + #tostring(w5), {Length = #tostring(miss), Diffuse = byJudgment("TapNoteScore_Miss")}) + else + self:settextf("%0.2f%% | %d - %d - %d - %d - %d - %d",math.floor(score*10000)/100, w1, w2, w3, w4, w5, miss) + self:AddAttribute(9, {Length = #tostring(w1), Diffuse = byJudgment("TapNoteScore_W1")}) + self:AddAttribute(12 + #tostring(w1), {Length = #tostring(w2), Diffuse = byJudgment("TapNoteScore_W2")}) + self:AddAttribute(15 + #tostring(w1) + #tostring(w2), {Length = #tostring(w3), Diffuse = byJudgment("TapNoteScore_W3")}) + self:AddAttribute(18 + #tostring(w1) + #tostring(w2) + #tostring(w3), {Length = #tostring(w4), Diffuse = byJudgment("TapNoteScore_W4")}) + self:AddAttribute(21 + #tostring(w1) + #tostring(w2) + #tostring(w3) + #tostring(w4), {Length = #tostring(w5), Diffuse = byJudgment("TapNoteScore_W5")}) + self:AddAttribute(24 + #tostring(w1) + #tostring(w2) + #tostring(w3) + #tostring(w4) + #tostring(w5), {Length = #tostring(miss), Diffuse = byJudgment("TapNoteScore_Miss")}) + end + end + } + -- date and ssr + d[#d+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(45,scoreItemHeight/4 * 3) + self:halign(0) + self:zoom(0.3) + end, + SetCommand = function(self) + if scoreList[scoreIndex] == nil then + return + end + local date = scoreList[scoreIndex]:GetDate() + local ssr = scoreList[scoreIndex]:GetSkillsetSSR("Overall") + self:settextf("%s | %0.2f", date, ssr) + self:AddAttribute(#date + #" | ", {Length = -1, Diffuse = byMSD(ssr)}) + end + } + + -- BG quad for score item player info + d[#d+1] = quadButton(6) .. { + InitCommand = function(self) + self:addx(scoreItemWidth + 10) + self:halign(0):valign(0) + self:diffusealpha(0.1) + self:zoomto(frameWidth - scoreItemWidth - scoreItemX - 20, scoreItemHeight) + end, + TopPressedCommand = function(self) + if scoreList[scoreIndex] == nil or not scoreList[scoreIndex]:HasReplayData() then + return + end + GHETTOGAMESTATE:setReplay(scoreList[scoreIndex], not isLocal) + SCREENMAN:GetTopScreen():Cancel() + end + } + + -- Tiny green box that means the score has replay data + d[#d+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + InitCommand = function(self) + self:addx(scoreItemWidth + 10 + (frameWidth - scoreItemWidth - scoreItemX - 20) - 5) + self:addy(scoreItemHeight * 3/4) + self:diffuse(color("#00ff00")) + self:zoom(0.12) + self:visible(false) + self:rotationz(90) + end, + SetCommand = function(self) + if scoreList[scoreIndex] == nil then + return + end + self:visible(scoreList[scoreIndex]:HasReplayData()) + end + } + + -- player name + d[#d+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(scoreItemWidth + 10 + (frameWidth - scoreItemWidth - scoreItemX - 20)/2,scoreItemHeight/4) + self:maxwidth((frameWidth - scoreItemWidth - scoreItemX - 20)*3) + self:zoom(0.3) + end, + SetCommand = function(self) + if scoreList[scoreIndex] == nil then + return + end + local name = profile:GetDisplayName() + if not isLocal then + name = scoreList[scoreIndex]:GetDisplayName() + end + self:settext(name) + end + } + + -- rate + d[#d+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(scoreItemWidth + 10 + (frameWidth - scoreItemWidth - scoreItemX - 20)/2,scoreItemHeight/4 * 3) + self:maxwidth((frameWidth - scoreItemWidth - scoreItemX - 20)*3) + self:zoom(0.3) + end, + SetCommand = function(self) + if scoreList[scoreIndex] == nil then + return + end + local ratestring = "("..string.format("%.2f", scoreList[scoreIndex]:GetMusicRate()):gsub("%.?0$", "") .. "x)" + self:settext(ratestring) + end + } + + + return d + + end + + for i=1, scoresPerPage do + t[#t+1] = scoreItem(i) + end + + + return t + end +local newScoreboard = themeConfig:get_data().global.EvalScoreboard +local inMulti = NSMAN:IsETTP() and IsSMOnlineLoggedIn() or false +if newScoreboard and not inMulti then + t[#t+1] = boardOfScores() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X*3/2-frameWidth/2, SCREEN_HEIGHT - 180 - 150) + end + } +elseif not inMulti then + t[#t+1] = LoadActor("scoreboard") +else + t[#t+1] = LoadActor("MPscoreboard") +end + + +local function offsetInput(event) + if event.type == "InputEventType_FirstPress" then + local outputName = "" + if event.button == "EffectUp" then + outputName = "NextJudge" + elseif event.button == "EffectDown" then + outputName = "PrevJudge" + elseif event.button == "MenuDown" then + outputName = "ToggleHands" + elseif event.button == "MenuUp" then + outputName = "ResetJudge" + end + + if outputName ~= "" then + MESSAGEMAN:Broadcast("OffsetPlotModification", {Name = outputName}) + end + end +end +t[#t+1] = LoadActor(THEME:GetPathG("","OffsetGraph"))..{ + InitCommand = function(self, params) + self:xy(SCREEN_CENTER_X*3/2-frameWidth/2, SCREEN_HEIGHT - 180) + self:zoom(0.5) + + local pn = GAMESTATE:GetEnabledPlayers()[1] + local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(pn) + local steps = GAMESTATE:GetCurrentSteps(pn) + + self:RunCommandsOnChildren(function(self) + local params = {width = frameWidth, + height = 150, + song = song, + steps = steps, + nrv = nrv, + dvt = dvt, + ctt = ctt, + ntt = ntt, + columns = steps:GetNumColumns()} + self:playcommand("Update", params) end + ) + end, + ShowScoreOffsetMessageCommand = function(self, params) + if scoreList[offsetIndex]:HasReplayData() then + if not offsetisLocal then + DLMAN:RequestOnlineScoreReplayData( + scoreList[offsetIndex], + function() + MESSAGEMAN:Broadcast("DelayedShowOffset") + end + ) + else + MESSAGEMAN:Broadcast("DelayedShowOffset") + end + else + self:RunCommandsOnChildren(function(self) self:playcommand("Update", {width = frameWidth, height = 150}) end) + end + end, + DelayedShowOffsetMessageCommand = function(self) + self:RunCommandsOnChildren(function(self) + local params = {width = frameWidth, + height = 150, + song = song, + steps = steps, + nrv = scoreList[offsetIndex]:GetNoteRowVector(), + dvt = scoreList[offsetIndex]:GetOffsetVector(), + ctt = scoreList[offsetIndex]:GetTrackVector(), + ntt = scoreList[offsetIndex]:GetTapNoteTypeVector(), + columns = steps:GetNumColumns()} + self:playcommand("Update", params) end + ) + end, + OnCommand = function(self) + self:stoptweening() + self:zoom(1) + self:addy(25) + self:bouncy(0.2) + self:addy(-25) + self:xy(SCREEN_CENTER_X*3/2-frameWidth/2, SCREEN_HEIGHT - 180) + self:diffusealpha(1) + SCREENMAN:GetTopScreen():AddInputCallback(offsetInput) + end, + OffCommand = function(self) + self:stoptweening() + self:bouncy(0.2) + self:x(SCREEN_CENTER_X*3/2-frameWidth/2 + 100) + self:diffusealpha(0) + end + +} + +-- Missing noterows text +t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(SCREEN_WIDTH * 3/4, SCREEN_HEIGHT * 3/4) + self:settext("Missing Noterows from Online Replay\n(゜´Д`゜)") + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.6) + self:visible(false) + end, + DelayedShowOffsetMessageCommand = function(self) + if scoreList[offsetIndex]:GetNoteRowVector() == nil then + self:visible(true) + else + self:visible(false) + end + end +} return t \ No newline at end of file diff --git a/BGAnimations/ScreenEvaluation decorations/scoreboard.lua b/BGAnimations/ScreenEvaluation decorations/scoreboard.lua new file mode 100644 index 00000000..73ee81e0 --- /dev/null +++ b/BGAnimations/ScreenEvaluation decorations/scoreboard.lua @@ -0,0 +1,418 @@ +local lines = 4 -- number of scores to display +local frameWidth = 260 +local frameX = SCREEN_WIDTH-frameWidth-WideScale(get43size(40),40)/2 +local frameY = 165 +local spacing = 34 + +local song = STATSMAN:GetCurStageStats():GetPlayedSongs()[1] + +local profile +local steps +local origTable +local hsTable +local rtTable +local scoreIndex +local score +local pss +local player = GAMESTATE:GetEnabledPlayers()[1] + + +pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(player) +profile = GetPlayerOrMachineProfile(player) +steps = STATSMAN:GetCurStageStats():GetPlayerStageStats(player):GetPlayedSteps()[1] +hsTable = getScoreTable(player, getCurRate()) +score = pss:GetHighScore() +scoreIndex = getHighScoreIndex(hsTable, score) + +local curPage = 1 +local maxPages = math.ceil(#hsTable/lines) + +local function movePage(n) + if n > 0 then + curPage = ((curPage+n-1) % maxPages + 1) + else + curPage = ((curPage+n+maxPages-1) % maxPages+1) + end + MESSAGEMAN:Broadcast("UpdatePage") +end + +local function scoreboardInput(event) + if event.type == "InputEventType_FirstPress" then + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + end + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + end + if event.button == "MenuLeft" then + movePage(-1) + end + + if event.button == "MenuRight" then + movePage(1) + end + + end +end + +local t = Def.ActorFrame{ + Name="scoreBoard", + OnCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(scoreboardInput) + end +} + +local function scoreitem(pn,index,scoreIndex,drawindex) + + --Whether the score at index is the score that was just played. + local equals = (index == scoreIndex) + + -- + local t = Def.ActorFrame { + Name="scoreItem"..tostring(drawindex), + InitCommand = function(self) + self:diffusealpha(0) + self:x(100) + end, + OnCommand = function(self) + self:stoptweening() + self:bouncy(0.2+index*0.05) + self:x(0) + if hsTable[index] == nil then + self:diffusealpha(0) + else + self:diffusealpha(1) + end + end, + OffCommand = function(self) + self:stoptweening() + self:bouncy(0.2+index*0.05) + self:x(100) + self:diffusealpha(0) + end, + ShowCommand = function(self) + self:playcommand("Set") + self:x(100) + self:diffusealpha(0) + self:finishtweening() + self:sleep((drawindex)*0.03) + self:easeOut(1) + self:x(0) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + self:x(SCREEN_WIDTH*10) + end, + UpdatePageMessageCommand = function(self) + index = (curPage - 1) * lines + drawindex+1 + equals = (index == scoreIndex) + if hsTable[index] ~= nil then + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + + --The main quad + Def.Quad{ + InitCommand=function(self) + self:xy(frameX,frameY+(drawindex*spacing)-4):zoomto(frameWidth,30):halign(0):valign(0):diffuse(getMainColor("frame")):diffusealpha(0.8) + end, + BeginCommand=function(self) + self:visible(GAMESTATE:IsHumanPlayer(pn)) + end + }, + + --Highlight quad for the current score + Def.Quad{ + InitCommand=function(self) + self:xy(frameX,frameY+(drawindex*spacing)-4):zoomto(frameWidth,30):halign(0):valign(0):diffuse(getMainColor("highlight")):diffusealpha(0.3) + end, + BeginCommand=function(self) + self:visible(GAMESTATE:IsHumanPlayer(pn) and equals) + end, + SetCommand = function(self) + self:playcommand("Begin") + end, + MouseLeftClickMessageCommand = function(self) + if self:isOver() then + self:GetParent():GetChild("grade"):visible(not self:GetParent():GetChild("grade"):GetVisible()) + self:GetParent():GetChild("judge"):visible(not self:GetParent():GetChild("judge"):GetVisible()) + self:GetParent():GetChild("date"):visible(not self:GetParent():GetChild("date"):GetVisible()) + self:GetParent():GetChild("option"):visible(not self:GetParent():GetChild("option"):GetVisible()) + end + end + }, + + --Quad that will act as the bounding box for mouse rollover/click stuff. + Def.Quad{ + Name="mouseOver", + InitCommand=function(self) + self:xy(frameX,frameY+(drawindex*spacing)-4):zoomto(frameWidth,30):halign(0):valign(0):diffuse(getMainColor('highlight')):diffusealpha(0.05) + end, + BeginCommand=function(self) + self:visible(false) + end + }, + + --ClearType lamps + Def.Quad{ + InitCommand=function(self) + self:xy(frameX,frameY+(drawindex*spacing)-4):zoomto(8,30):halign(0):valign(0) + end, + BeginCommand=function(self) + self:playcommand("Set") + end, + SetCommand = function(self) + if hsTable[index] ~= nil then + self:diffuse(getClearTypeColor(getClearType(pn,steps,hsTable[index]))) + self:visible(GAMESTATE:IsHumanPlayer(pn)) + end + end + }, + + --Animation(?) for ClearType lamps + Def.Quad{ + InitCommand=function(self) + self:xy(frameX,frameY+(drawindex*spacing)-4):zoomto(8,30):halign(0):valign(0):diffusealpha(0.3) + end, + BeginCommand=function(self) + self:playcommand("Set") + end, + SetCommand = function(self) + if hsTable[index] ~= nil then + self:diffuse(getClearTypeColor(getClearType(pn,steps,hsTable[index]))) + self:visible(GAMESTATE:IsHumanPlayer(pn)) + self:diffuseramp() + self:effectoffset(0.03*(lines-drawindex)) + self:effectcolor2(color("1,1,1,0.6")) + self:effectcolor1(color("1,1,1,0")) + self:effecttiming(2,1,0,0) + end + end + }, + + + --rank + LoadFont("Common normal")..{ + InitCommand=function(self) + self:xy(frameX-8,frameY+12+(drawindex*spacing)):zoom(0.35) + end, + BeginCommand=function(self) + self:playcommand("Set") + end, + SetCommand = function(self) + if #hsTable >= 1 then + self:settext(index) + if equals then + self:diffuseshift() + self:effectcolor1(color(colorConfig:get_data().evaluation.BackgroundText)) + self:effectcolor2(color("#3399cc")) + self:effectperiod(0.1) + else + self:stopeffect() + self:diffuse(color(colorConfig:get_data().evaluation.BackgroundText)) + end + end + end + }, + + --grade and %score + LoadFont("Common normal")..{ + Name="grade", + InitCommand=function(self) + self:xy(frameX+10,frameY+11+(drawindex*spacing)):zoom(0.35):halign(0):maxwidth((frameWidth-15)/0.35) + end, + BeginCommand=function(self) + self:playcommand("Set") + end, + SetCommand = function(self) + if hsTable[index] ~= nil then + local pscore = hsTable[index]:GetWifeScore() + self:diffuse(color(colorConfig:get_data().evaluation.ScoreBoardText)) + self:settextf("%s %.2f%% (x%d)",(getGradeStrings(hsTable[index]:GetWifeGrade())),math.floor((pscore)*10000)/100,hsTable[index]:GetMaxCombo()) + end + end + }, + + --mods + LoadFont("Common normal")..{ + Name="option", + InitCommand=function(self) + self:xy(frameX+10,frameY+11+(drawindex*spacing)):zoom(0.35):halign(0):maxwidth((frameWidth-15)/0.35) + end, + BeginCommand=function(self) + self:playcommand("Set") + end, + SetCommand = function(self) + if hsTable[index] ~= nil then + self:diffuse(color(colorConfig:get_data().evaluation.ScoreBoardText)) + self:settext(hsTable[index]:GetModifiers()) + self:visible(false) + end + end + }, + + --cleartype text + LoadFont("Common normal")..{ + InitCommand=function(self) + self:xy(frameX+10,frameY+2+(drawindex*spacing)):zoom(0.35):halign(0):maxwidth((frameWidth-15)/0.35) + end, + BeginCommand=function(self) + self:playcommand("Set") + end, + SetCommand = function(self) + if hsTable[index] ~= nil then + if #hsTable >= 1 and index>= 1 then + self:settext(getClearTypeText(getClearType(pn,steps,hsTable[index]))) + self:diffuse(getClearTypeColor(getClearType(pn,steps,hsTable[index]))) + end + end + end + }, + + --judgment + LoadFont("Common normal")..{ + Name="judge", + InitCommand=function(self) + self:xy(frameX+10,frameY+20+(drawindex*spacing)):zoom(0.35):halign(0):maxwidth((frameWidth-15)/0.35) + end, + BeginCommand=function(self) + self:playcommand("Set") + end, + SetCommand = function(self) + if hsTable[index] ~= nil then + if #hsTable >= 1 and index>= 1 then + self:settextf("%d / %d / %d / %d / %d / %d", + hsTable[index]:GetTapNoteScore("TapNoteScore_W1"), + hsTable[index]:GetTapNoteScore("TapNoteScore_W2"), + hsTable[index]:GetTapNoteScore("TapNoteScore_W3"), + hsTable[index]:GetTapNoteScore("TapNoteScore_W4"), + hsTable[index]:GetTapNoteScore("TapNoteScore_W5"), + hsTable[index]:GetTapNoteScore("TapNoteScore_Miss")) + end + self:diffuse(color(colorConfig:get_data().evaluation.ScoreBoardText)) + end + end + }, + + --date + LoadFont("Common normal")..{ + Name="date", + InitCommand=function(self) + self:xy(frameX+10,frameY+20+(drawindex*spacing)):zoom(0.35):halign(0) + end, + BeginCommand=function(self) + self:playcommand("Set") + end, + SetCommand = function(self) + if hsTable[index] ~= nil then + self:diffuse(color(colorConfig:get_data().evaluation.ScoreBoardText)) + if #hsTable >= 1 and index>= 1 then + self:settext(hsTable[index]:GetDate()) + end + self:visible(false) + end + end + } + + } + return t +end + +--can't have more lines than the # of scores huehuehu +if lines > #hsTable then + lines = #hsTable +end + +local drawindex = 0 +curPage = math.ceil(scoreIndex / lines) +local startind = (curPage-1) * lines + 1 + +while drawindex < 4 do + t[#t+1] = scoreitem(player,startind,scoreIndex,drawindex) + startind = startind+1 + drawindex = drawindex+1 +end + +--Text that sits above the scoreboard with some info +t[#t+1] = LoadFont("Common normal")..{ + InitCommand=function(self) + self:xy(frameX + frameWidth/2,frameY-15):zoom(0.35) + end, + BeginCommand=function(self) + local text = "" + if scoreIndex ~= 0 then + if themeConfig:get_data().global.RateSort then + text = string.format("Rate %s - Rank %d/%d",getRate(score),scoreIndex,(#hsTable)) + else + text = string.format("Rank %d/%d",scoreIndex,(#hsTable)) + end + else + if themeConfig:get_data().global.RateSort then + text = string.format("Rate %s - Out of rank",getRate(score)) + else + text = "Out of rank" + end + end + self:settext(text) + self:diffuse(color(colorConfig:get_data().evaluation.BackgroundText)):diffusealpha(0.8) + end, + TabChangedMessageCommand = function(self, params) + if params.index == 1 then + self:stoptweening() + self:bouncy(0.3) + self:diffusealpha(1) + else + self:stoptweening() + self:bouncy(0.3) + self:diffusealpha(0) + end + end +} + +--Update function for showing mouse rollovers +local function Update(self) + t.InitCommand=function(self) + self:SetUpdateFunction(Update) + end + for i=0,drawindex-1 do + if self:GetChild("scoreItem"..tostring(i)):GetChild("mouseOver"):isOver() then + self:GetChild("scoreItem"..tostring(i)):GetChild("mouseOver"):visible(true) + else + self:GetChild("scoreItem"..tostring(i)):GetChild("mouseOver"):visible(false) + self:GetChild("scoreItem"..tostring(i)):GetChild("grade"):visible(true) + self:GetChild("scoreItem"..tostring(i)):GetChild("judge"):visible(true) + self:GetChild("scoreItem"..tostring(i)):GetChild("date"):visible(false) + self:GetChild("scoreItem"..tostring(i)):GetChild("option"):visible(false) + end + end +end +t.InitCommand=function(self) + self:SetUpdateFunction(Update) +end + +t[#t+1] = Def.Quad { + InitCommand = function(self) + self:xy(frameX - 20,frameY - 20) + self:valign(0):halign(0) + self:diffusealpha(0) + self:zoomto(20 + frameWidth, 20 + (30) * lines + lines * (5)) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() then + movePage(1) + end + end + +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenEvaluation overlay/default.lua b/BGAnimations/ScreenEvaluation overlay/default.lua index baaf7ea2..318616d1 100644 --- a/BGAnimations/ScreenEvaluation overlay/default.lua +++ b/BGAnimations/ScreenEvaluation overlay/default.lua @@ -4,27 +4,8 @@ local profile = GetPlayerOrMachineProfile(pn) local steps = GAMESTATE:GetCurrentSteps(pn) -t[#t+1] = LoadActor("../_frame"); -t[#t+1] = LoadActor("../_mouse"); - -local curTab = 1 -local function input(event) - if event.type == "InputEventType_FirstPress" then - -- For swapping back and forth between scoreboard and offset display. - for i=1,2 do - if event.DeviceInput.button == "DeviceButton_"..i then - if i ~= curTab then - curTab = i - MESSAGEMAN:Broadcast("TabChanged",{index = i}) - SOUND:PlayOnce(THEME:GetPathS("","whoosh"),true) - end - end - end - - end - return false -end - +t[#t+1] = LoadActor("../_frame") +t[#t+1] = LoadActor("../_mouse") --Group folder name local frameWidth = 280 @@ -35,37 +16,37 @@ local frameY = 10 t[#t+1] = Def.ActorFrame{ InitCommand = function(self) self:xy(frameX,frameY) - end; + end, OnCommand = function(self) - SCREENMAN:GetTopScreen():AddInputCallback(input) self:y(-frameHeight/2) self:smooth(0.5) self:y(frameY) - end; + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end, OffCommand = function(self) self:smooth(0.5) self:y(-frameHeight/2) - end; + end, Def.Quad{ InitCommand=function(self) self:halign(1):zoomto(frameWidth,frameHeight):diffuse(getMainColor('highlight')):diffusealpha(0.8) - end; - }; + end + }, LoadFont("Common Normal") .. { InitCommand=function(self) self:x(-frameWidth+5):halign(0):zoom(0.45):maxwidth((frameWidth-10)/0.45) - end; + end, BeginCommand=function(self) self:diffuse(color(colorConfig:get_data().main.headerFrameText)) local song = GAMESTATE:GetCurrentSong() if song ~= nil then self:settext(song:GetGroupName()) - end; - end; - }; + end + end + } } -t[#t+1] = LoadActor("../_cursor"); +t[#t+1] = LoadActor("../_cursor") diff --git a/BGAnimations/ScreenEvaluation underlay.lua b/BGAnimations/ScreenEvaluation underlay.lua index b10e40ad..50fa6a9a 100644 --- a/BGAnimations/ScreenEvaluation underlay.lua +++ b/BGAnimations/ScreenEvaluation underlay.lua @@ -8,7 +8,7 @@ local maxDistY = SCREEN_HEIGHT*magnitude -- 3 = the pool will be grade specific bgs only. unless it doesn't exist in which case it will revert to the clear bg pool. -- Fails will only use the Grade_Failed folder. local bgType = themeConfig:get_data().eval.SongBGType -- 1 = disabled, 2 = songbg, 3 = playerbg -local enabled = themeConfig:get_data().global.SongBGEnabled and not(GAMESTATE:IsCourseMode()) +local enabled = themeConfig:get_data().global.SongBGEnabled local moveBG = themeConfig:get_data().global.SongBGMouseEnabled and enabled local brightness = 0.4 @@ -18,16 +18,16 @@ t[#t+1] = LoadActor("_background") if enabled and bgType == 1 then -- SONG BG t[#t+1] = LoadSongBackground()..{ - Name="MouseXY"; + Name="MouseXY", BeginCommand=function(self) if moveBG then self:scaletocover(0-maxDistX/8,0-maxDistY/8,SCREEN_WIDTH+maxDistX/8,SCREEN_BOTTOM+maxDistY/8) - self:diffusealpha(brightness); + self:diffusealpha(brightness) else self:scaletocover(0,0,SCREEN_WIDTH,SCREEN_BOTTOM) - self:diffusealpha(brightness); + self:diffusealpha(brightness) end - end; + end } end @@ -38,13 +38,11 @@ if enabled and bgType > 1 then -- 2 = Grade+Clear, 3 = Grade Only -- Get the highest grade from the player (or players if 2P) local pss local highestGrade = "Grade_Failed" - for k,v in pairs({PLAYER_1,PLAYER_2}) do - if GAMESTATE:IsPlayerEnabled(v) then - pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(v) - local playerGrade = pss:GetGrade() - if Enum.Reverse(Grade)[playerGrade] < Enum.Reverse(Grade)[highestGrade] then - highestGrade = playerGrade - end + if GAMESTATE:IsPlayerEnabled(PLAYER_1) then + pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(PLAYER_1) + local playerGrade = pss:GetGrade() + if Enum.Reverse(Grade)[playerGrade] < Enum.Reverse(Grade)[highestGrade] then + highestGrade = playerGrade end end @@ -80,22 +78,22 @@ if enabled and bgType > 1 then -- 2 = Grade+Clear, 3 = Grade Only local bgList = filterFileList(bgList,imgTypes) t[#t+1] = Def.Sprite { - Name="MouseXY"; + Name="MouseXY", BeginCommand=function(self) if #bgList > 0 then local bg = bgList[math.random(#bgList)] --SCREENMAN:SystemMessage(string.format("Loading %s",bg)) - self:LoadBackground(bg); + self:LoadBackground(bg) end if moveBG then self:scaletocover(0-maxDistX/8,0-maxDistY/8,SCREEN_WIDTH+maxDistX/8,SCREEN_BOTTOM+maxDistY/8) - self:diffusealpha(brightness); + self:diffusealpha(brightness) else self:scaletocover(0,0,SCREEN_WIDTH,SCREEN_BOTTOM) - self:diffusealpha(brightness); + self:diffusealpha(brightness) end - end; - }; + end + } end t[#t+1] = LoadActor("_particles") @@ -132,32 +130,32 @@ local function getPosY() offset = math.abs(offset) if offset > 1 then offset = math.min(2*math.sqrt(offset),maxDistY) - end; + end else neg = false offset = math.abs(offset) if offset > 1 then offset = math.min(2*math.sqrt(offset),maxDistY) - end; - end; + end + end if neg then return SCREEN_CENTER_Y+offset else return SCREEN_CENTER_Y-offset - end; + end end local function Update(self) t.InitCommand=function(self) self:SetUpdateFunction(Update) - end; + end self:GetChild("MouseXY"):xy(getPosX(),getPosY()) -end; +end if moveBG then t.InitCommand=function(self) self:SetUpdateFunction(Update) - end; -end; + end +end return t diff --git a/BGAnimations/ScreenFileTagManager decorations/default.lua b/BGAnimations/ScreenFileTagManager decorations/default.lua new file mode 100644 index 00000000..a8235dec --- /dev/null +++ b/BGAnimations/ScreenFileTagManager decorations/default.lua @@ -0,0 +1,3 @@ +local t = Def.ActorFrame{} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenMusicInfo in.lua b/BGAnimations/ScreenFileTagManager out.lua similarity index 100% rename from BGAnimations/ScreenMusicInfo in.lua rename to BGAnimations/ScreenFileTagManager out.lua diff --git a/BGAnimations/ScreenFileTagManager overlay/default.lua b/BGAnimations/ScreenFileTagManager overlay/default.lua new file mode 100644 index 00000000..5bf83007 --- /dev/null +++ b/BGAnimations/ScreenFileTagManager overlay/default.lua @@ -0,0 +1,530 @@ +local maxTags = 16 +local maxPages = 1 +local curPage = 1 +local ptags = tags:get_data().playerTags +local playertags = {} +local filterTags = GHETTOGAMESTATE:getFilterTags() +local tagName +local steps = GAMESTATE:GetCurrentSteps(PLAYER_1) +local ck = steps:GetChartKey() +local song = GAMESTATE:GetCurrentSong() + +local function updateTagsFromData() + ptags = tags:get_data().playerTags + playertags = {} + for k,v in pairs(ptags) do + playertags[#playertags+1] = k + end + table.sort(playertags, function(left, right) + if ptags[left][ck] == ptags[right][ck] then + return left:lower() < right:lower() + else + return ptags[left][ck] ~= nil and ptags[right][ck] == nil + end + end) + curPage = 1 + maxPages = math.ceil(#playertags/maxTags) +end + +local function movePage(n) + if maxPages > 1 then + if n > 0 then + curPage = ((curPage+n-1) % maxPages + 1) + else + curPage = ((curPage+n+maxPages-1) % maxPages+1) + end + end + MESSAGEMAN:Broadcast("UpdateList") +end + +local function input(event) + + if event.type == "InputEventType_FirstPress" then + if event.button == "Back" or event.button == "Start" then + SCREENMAN:GetTopScreen():Cancel() + elseif event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + elseif event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + elseif event.button == "MenuLeft" then + movePage(-1) + elseif event.button == "MenuRight" then + movePage(1) + end + end + + + return false +end + +local top +local leftSectionWidth = 300 +local leftSectionHeight = SCREEN_HEIGHT - 60 +local leftUpperSectionHeight = leftSectionHeight / 3 +local leftLowerSectionHeight = leftSectionHeight / 2 + 63 +local rightSectionWidth = 430 +local rightSectionHeight = SCREEN_HEIGHT - 140 + +local verticalSpacing = 7 +local horizontalSpacing = 10 + + +local t = Def.ActorFrame { + OnCommand = function(self) + everything = self + top = SCREENMAN:GetTopScreen() + top:AddInputCallback(input) + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end +} + +local boxHeight = 20 +local numBoxWidth = leftSectionWidth / 5 +local boundHorizontalSpacing = 8 +local boundVerticalSpacing = 2 + +t[#t+1] = LoadActor("../_mouse") + +t[#t+1] = LoadActor("../_frame") + +local frameWidth = 430 +local frameHeight = 340 +local function topRow() + local frameWidth = SCREEN_WIDTH - 20 + local frameHeight = 40 + + local t = Def.ActorFrame{ + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + end + } + + t[#t+1] = Def.Sprite { + Name = "Banner", + InitCommand = function(self) + self:x(-frameWidth/2 + 5) + self:halign(0) + local bnpath = song:GetBannerPath() + if not bnpath then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) + self:scaletoclipped(96, 30) + end + } + + t[#t+1] = LoadFont("Common BLarge") .. { + Name = "SongTitle", + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, -9) + self:zoom(0.25) + self:halign(0) + self:settext(song:GetMainTitle()) + if #song:GetDisplaySubTitle() == 0 then + self:zoom(0.35):y(-5) + end + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + local actor = self:GetParent():GetChild("SongTitle") + local x = actor:GetX() + actor:GetWidth()*actor:GetZoomX() + 2 + local y = actor:GetY() - 2 + + self:xy(x,y) + self:zoom(0.3) + self:halign(0) + self:playcommand("Set") + end, + SetCommand = function(self) + local length = song:GetStepsSeconds()/getCurRateValue() + self:settextf("%s",SecondsToMSS(length)) + self:diffuse(getSongLengthColor(length)) + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 1) + self:zoom(0.35) + self:halign(0) + self:settext(song:GetDisplaySubTitle()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 9) + self:zoom(0.35) + self:halign(0) + self:settext("// "..song:GetDisplayArtist()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,-1) + self:zoom(0.5) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local diff = curSteps:GetDifficulty() + local stype = curSteps:GetStepsType() + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + meter = curSteps:GetMeter() + end + + local difftext + if diff == 'Difficulty_Edit' then + difftext = curSteps:GetDescription() + difftext = difftext == '' and getDifficulty(diff) or difftext + else + difftext = getDifficulty(diff) + end + + self:settext(ToEnumShortString(stype):gsub("%_"," ").." "..difftext.." "..meter) + self:diffuse(getDifficultyColor(GetCustomDifficulty(stype,diff))) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,9) + self:zoom(0.35) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local notes = 0 + if curSteps ~= nil then + notes = curSteps:GetRadarValues(pn):GetValue("RadarCategory_Notes") + end + self:settextf("%d Notes", notes) + self:diffuse(Saturation(getDifficultyColor(GetCustomDifficulty(curSteps:GetStepsType(),curSteps:GetDifficulty())),0.3)) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name="MSDAvailability", + InitCommand = function(self) + self:xy(frameWidth/2-5,-11) + self:zoom(0.30) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + if curSteps ~= nil then + + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + self:settext("Default") + self:diffuse(color(colorConfig:get_data().main.disabled)) + else + self:settext("MSD") + self:diffuse(color(colorConfig:get_data().main.enabled)) + end + end + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "round_star")) .. { + InitCommand = function(self) + self:xy(-frameWidth/2+1,-frameHeight/2+1) + self:zoom(0.3) + self:wag() + self:diffuse(Color.Yellow) + + if not song:IsFavorited() then + self:visible(false) + end + end + } + + return t +end + +-- The lower left container (The Filter Menu) +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(10,30 + leftUpperSectionHeight + verticalSpacing) + end, + + Def.Quad { + InitCommand = function (self) + self:zoomto(leftSectionWidth,leftLowerSectionHeight/2) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end, + }, + Def.Quad { + InitCommand = function(self) + boundSection = self + self:xy(10 + numBoxWidth,42) + self:zoomto(numBoxWidth * 2 + boundHorizontalSpacing, boxHeight * (#ms.SkillSets+1) + boundVerticalSpacing * #ms.SkillSets) + self:halign(0):valign(0) + self:diffusealpha(0) + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Tagging") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(5,25) + self:zoom(0.35) + self:halign(0) + self:valign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Left click a Tag to assign this file that tag.\nRight click a Tag to unassign the tag.\nYou can filter songs by Tag in the Filtering menu.\nAssigned tags have a distinct color from others.") + end + }, + quadButton(6) .. { + InitCommand = function(self) + self:xy(15, leftLowerSectionHeight/2 - 30) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(numBoxWidth + 15, 35) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + local tagname = function(ans) + tagName = ans + self:GetParent():GetParent():GetChild("TagContainer"):queuecommand("SaveNewTag") + end + easyInputStringWithFunction("Tag Name:", 255, false, tagname) + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(15 + (numBoxWidth+15)/2,leftLowerSectionHeight/2 - 30) + self:zoom(0.4) + self:settext("Create Tag") + end + } +} + +-- The right container (The Tags Menu) +local function rightContainer() + + local boxHeight = 25 + local boxWidth = rightSectionWidth / 3 + + local t = Def.ActorFrame { + Name = "TagContainer", + InitCommand = function(self) + self:xy(20 + leftSectionWidth,110) + updateTagsFromData() + MESSAGEMAN:Broadcast("UpdateList") + end, + SaveNewTagCommand = function(self) + if tagName ~= "" and ptags[tagName] == nil then + tags:get_data().playerTags[tagName] = {} + tags:set_dirty() + tags:save() + updateTagsFromData() + MESSAGEMAN:Broadcast("UpdateList") + end + end, + + -- The container quad + Def.Quad { + InitCommand = function (self) + self:zoomto(rightSectionWidth,rightSectionHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() then + movePage(1) + end + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Assign Tags") + end + } + } + + -- this is copied straight from the pack downloader screen + -- theming is so easy lol + local function tagItem(i) + local tagIndex = (curPage-1)*10+i + + local r = Def.ActorFrame{ + InitCommand = function(self) + self:diffusealpha(0) + self:xy(25 + boxWidth*1.5*((tagIndex-1) % maxTags >= maxTags/2 and 1 or 0), 30 + ((i-1) % math.floor(maxTags/2))*(boxHeight+verticalSpacing)-10) + self:playcommand("Show") + end, + ShowCommand = function(self) + self:y(30 + ((i-1) % math.floor(maxTags/2))*(boxHeight+verticalSpacing)-10) + self:diffusealpha(0) + self:finishtweening() + self:sleep((i-1)*0.01) + self:easeOut(0.3) + self:y(30 + ((i-1) % math.floor(maxTags/2))*(boxHeight+verticalSpacing)+25) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + end, + UpdateListMessageCommand = function(self) + tagIndex = (curPage-1)*10+i + if playertags[tagIndex] ~= nil then + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end + } + + -- Tag index number + r[#r+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(-10,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + end, + SetCommand = function(self) + self:settextf("%d", tagIndex) + end + } + + -- The tag button + r[#r+1] = quadButton(6) .. { + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(boxWidth, boxHeight) + end, + TopPressedCommand = function(self, params) + if playertags[tagIndex] ~= nil then + if params.input == "DeviceButton_left mouse button" then + if not ptags[playertags[tagIndex]][ck] then + tags:get_data().playerTags[playertags[tagIndex]][ck] = 1 + tags:set_dirty() + tags:save() + updateTagsFromData() + MESSAGEMAN:Broadcast("UpdateList") + end + elseif params.input == "DeviceButton_right mouse button" then + if ptags[playertags[tagIndex]][ck] then + tags:get_data().playerTags[playertags[tagIndex]][ck] = nil + tags:set_dirty() + tags:save() + updateTagsFromData() + MESSAGEMAN:Broadcast("UpdateList") + end + end + end + end, + SetCommand = function(self) + if ptags[playertags[tagIndex]][ck] then + self:diffusealpha(0.4) + else + self:diffusealpha(0.2) + end + end + } + + -- Tag name + r[#r+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(10,0):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + self:settextf("%s",playertags[tagIndex]) + self:maxwidth(boxWidth * 2) + end + } + + -- Color for the button to show assign status + r[#r+1] = Def.Quad{ + Name = "Status", + InitCommand = function(self) + self:halign(0) + self:diffuse(color(colorConfig:get_data().main.highlight)) + self:diffusealpha(0.8) + self:xy(0, 0) + self:zoomto(4, boxHeight) + end, + SetCommand = function(self) + if ptags[playertags[tagIndex]][ck] then + self:diffuse(getMiscColor("TagPositive")):diffusealpha(0.8) + else + self:diffuse(getMiscColor("TagNegative")):diffusealpha(0.8) + end + end + } + + return r + end + + for i = 1, maxTags do + t[#t+1] = tagItem(i) + end + + return t +end + +t[#t+1] = topRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(0) + end +} + +t[#t+1] = rightContainer() + +t[#t+1] = LoadActor("../_cursor") + +return t diff --git a/BGAnimations/ScreenFileTagManager underlay/default.lua b/BGAnimations/ScreenFileTagManager underlay/default.lua new file mode 100644 index 00000000..c7a31b85 --- /dev/null +++ b/BGAnimations/ScreenFileTagManager underlay/default.lua @@ -0,0 +1,10 @@ +local t = Def.ActorFrame{} + +t[#t+1] = Def.Quad { + InitCommand = function(self) + self:diffusealpha(0.8) + self:FullScreen() + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenFiltering decorations/default.lua b/BGAnimations/ScreenFiltering decorations/default.lua new file mode 100644 index 00000000..a8235dec --- /dev/null +++ b/BGAnimations/ScreenFiltering decorations/default.lua @@ -0,0 +1,3 @@ +local t = Def.ActorFrame{} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenPlayerProfile in.lua b/BGAnimations/ScreenFiltering out.lua similarity index 100% rename from BGAnimations/ScreenPlayerProfile in.lua rename to BGAnimations/ScreenFiltering out.lua diff --git a/BGAnimations/ScreenFiltering overlay/default.lua b/BGAnimations/ScreenFiltering overlay/default.lua new file mode 100644 index 00000000..1ba2ed88 --- /dev/null +++ b/BGAnimations/ScreenFiltering overlay/default.lua @@ -0,0 +1,854 @@ +local inputting = false +local activeField = {} +local filterFields = {} +filterFields["Lower"] = {} +filterFields["Upper"] = {} + +local boundSection +local everything + + +local maxTags = 20 +local maxPages = 1 +local curPage = 1 +local ptags = tags:get_data().playerTags +local playertags = {} +local filterTags = GHETTOGAMESTATE:getFilterTags() +local tagName +local tagFilterMode = GHETTOGAMESTATE:getTagFilterMode() +local packlistFiltered + +for i = 1, #ms.SkillSets + 1 do -- the +1 is for the length field + filterFields["Lower"][i] = FILTERMAN:GetSSFilter(i, 0) + filterFields["Upper"][i] = FILTERMAN:GetSSFilter(i, 1) +end + +local function updateTagsFromData() + ptags = tags:get_data().playerTags + playertags = {} + for k,v in pairs(ptags) do + playertags[#playertags+1] = k + end + table.sort(playertags, function(left, right) + if filterTags[left] == filterTags[right] then + return left:lower() < right:lower() + else + return filterTags[left] ~= nil and filterTags[right] == nil + end + end) + curPage = 1 + maxPages = math.ceil(#playertags/maxTags) +end + +local function movePage(n) + if maxPages > 1 then + if n > 0 then + curPage = ((curPage+n-1) % maxPages + 1) + else + curPage = ((curPage+n+maxPages-1) % maxPages+1) + end + end + MESSAGEMAN:Broadcast("UpdateList") +end + +local function wheelSearch() + local search = GHETTOGAMESTATE:getMusicSearch() + GHETTOGAMESTATE:getSSM():GetMusicWheel():SongSearch(search) +end + +local function updateFilter() + for i = 1, #ms.SkillSets + 1 do + FILTERMAN:SetSSFilter(tonumber(filterFields["Lower"][i]), i, 0) + FILTERMAN:SetSSFilter(tonumber(filterFields["Upper"][i]), i, 1) + --FILTERMAN:SetSSFilter(tonumber(filterFields[activeField[1]][activeField[2]]), tonumber(activeField[1]), activeField[2] == "Upper" and 1 or 0) + end + wheelSearch() +end + +local function resetFilter() + FILTERMAN:ResetSSFilters() + for i = 1, #ms.SkillSets + 1 do -- the +1 is for the length field + filterFields["Lower"][i] = FILTERMAN:GetSSFilter(i, 0) + filterFields["Upper"][i] = FILTERMAN:GetSSFilter(i, 1) + end + wheelSearch() +end + +-- From Til Death: The "OR" and "AND" filter for tags +local function updateTagFilter() + ptags = tags:get_data().playerTags + local charts = {} + if next(filterTags) then + toFilterTags = {} + for k, v in pairs(filterTags) do + toFilterTags[#toFilterTags + 1] = k + end + if tagFilterMode then + local inCharts = {} + for k, v in pairs(ptags[toFilterTags[1]]) do + inCharts[k] = 1 + end + toFilterTags[1] = nil + for k, v in pairs(toFilterTags) do + for key, val in pairs(inCharts) do + if ptags[v][key] == nil then + inCharts[key] = nil + end + end + end + for k, v in pairs(inCharts) do + charts[#charts + 1] = k + end + else + for k, v in pairs(toFilterTags) do + for key, val in pairs(ptags[v]) do + if charts[key] == nil then + charts[#charts + 1] = key + end + end + end + end + end + GHETTOGAMESTATE:setFilterTags(filterTags) + GHETTOGAMESTATE:getSSM():GetMusicWheel():FilterByStepKeys(charts) + wheelSearch() +end + +local function updateSelected() + local bound = activeField[1] + local i = activeField[2] + everything:GetChild("BoundContainer"..i):GetChild(bound):queuecommand("Set") +end + +local function updateEverything() + for i = 1, #ms.SkillSets + 1 do + everything:GetChild("BoundContainer"..i):GetChild("Lower"):queuecommand("Set") + everything:GetChild("BoundContainer"..i):GetChild("Upper"):queuecommand("Set") + end +end + +local function disableInput() + inputting = false + --activeField = {} + MESSAGEMAN:Broadcast("FilterBoundSelect", {}) +end + +local function input(event) + + if event.type == "InputEventType_FirstPress" then + if not inputting then + if not inputting and (event.button == "Back" or event.button == "Start") then + SCREENMAN:GetTopScreen():Cancel() + elseif event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + elseif event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + elseif event.button == "MenuLeft" then + movePage(-1) + elseif event.button == "MenuRight" then + movePage(1) + end + elseif inputting then + local slotValue = tostring(filterFields[activeField[1]][activeField[2]]) + if event.DeviceInput.button == "DeviceButton_left mouse button" or event.DeviceInput.button == "DeviceButton_right mouse button" then + if not boundSection:isOver() then + disableInput() + end + elseif event.button == "Start" then + disableInput() + updateFilter() + elseif event.button == "Back" then + disableInput() + elseif tonumber(event.char) ~= nil then + if tonumber(slotValue .. event.char) ~= 0 and (slotValue .. event.char):len() < 6 then + filterFields[activeField[1]][activeField[2]] = tostring(tonumber(slotValue .. event.char)) + updateSelected() + end + elseif event.DeviceInput.button == "DeviceButton_backspace" then + local nextValue = slotValue:sub(1,-2) + if nextValue ~= nil and tonumber(nextValue) ~= slotValue then + if nextValue == "" then + filterFields[activeField[1]][activeField[2]] = "0" + else + filterFields[activeField[1]][activeField[2]] = nextValue + end + updateSelected() + end + elseif event.DeviceInput.button == "DeviceButton_delete" then + filterFields[activeField[1]][activeField[2]] = "0" + updateSelected() + end + end + end + + + return false +end + +local top +local leftSectionWidth = 300 +local leftSectionHeight = SCREEN_HEIGHT - 60 +local leftUpperSectionHeight = leftSectionHeight / 3 +local leftLowerSectionHeight = leftSectionHeight / 2 + 63 +local rightSectionWidth = 430 +local rightSectionHeight = SCREEN_HEIGHT - 60 + +local verticalSpacing = 7 +local horizontalSpacing = 10 + + +local t = Def.ActorFrame { + OnCommand = function(self) + everything = self + top = SCREENMAN:GetTopScreen() + top:AddInputCallback(input) + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end +} + +local boxHeight = 20 +local numBoxWidth = leftSectionWidth / 5 +local boundHorizontalSpacing = 8 +local boundVerticalSpacing = 2 + +-- make the boxes for lower and upper bounds +-- im gonna make this complicated and build an actorframe of 2 boxes +-- you cant stop me +local function boundBoxes(i) + local r = Def.ActorFrame { + Name = "BoundContainer"..i, + -- Skillset name (or Length) + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(20,leftUpperSectionHeight + verticalSpacing + 30 + 30 + (boxHeight + boundVerticalSpacing)*i) + self:zoom(0.4) + self:halign(0) + self:settext(i == #ms.SkillSets+1 and "Length" or ms.SkillSets[i]) + end + }, + -- Lower bound box + quadButton(3) .. { + Name = "LowerBound"..(i == (#ms.SkillSets+1) and "Length" or ms.SkillSets[i]), + InitCommand = function(self) + self:xy(20 + numBoxWidth,leftUpperSectionHeight + verticalSpacing + 30 + 30 + (boxHeight + boundVerticalSpacing)*i) + self:halign(0) + self:zoomto(numBoxWidth,boxHeight) + self:diffusealpha(0.2) + end, + TopPressedCommand = function(self) + self:diffusealpha(0.4) + inputting = true + activeField = {"Lower", i} + MESSAGEMAN:Broadcast("FilterBoundSelect", {bound = "Lower", selected = i}) + end, + FilterBoundSelectMessageCommand = function(self, params) + if params.selected ~= i or params.bound ~= "Lower" then + self:diffusealpha(0.2) + end + end + }, + LoadFont("Common Normal") ..{ + Name = "Lower", + InitCommand = function(self) + self:xy(25 + numBoxWidth,leftUpperSectionHeight + verticalSpacing + 30 + 30 + (boxHeight + boundVerticalSpacing)*i) + self:zoom(0.5) + self:halign(0) + self:settext("") + self:queuecommand("Set") + end, + SetCommand = function(self) + self:settext(filterFields["Lower"][i]) + end + }, + -- Upper bound box + quadButton(3) .. { + Name = "UpperBound"..(i == (#ms.SkillSets+1) and "Length" or ms.SkillSets[i]), + InitCommand = function(self) + self:xy(20 + numBoxWidth*2 + boundHorizontalSpacing,leftUpperSectionHeight + verticalSpacing + 30 + 30 + (boxHeight + boundVerticalSpacing)*i) + self:halign(0) + self:zoomto(numBoxWidth,boxHeight) + self:diffusealpha(0.2) + end, + TopPressedCommand = function(self) + self:diffusealpha(0.4) + inputting = true + activeField = {"Upper", i} + MESSAGEMAN:Broadcast("FilterBoundSelect", {bound = "Upper", selected = i}) + end, + FilterBoundSelectMessageCommand = function(self, params) + if params.selected ~= i or params.bound ~= "Upper" then + self:diffusealpha(0.2) + end + end + }, + LoadFont("Common Normal") ..{ + Name = "Upper", + InitCommand = function(self) + self:xy(25 + numBoxWidth*2 + boundHorizontalSpacing,leftUpperSectionHeight + verticalSpacing + 30 + 30 + (boxHeight + boundVerticalSpacing)*i) + self:zoom(0.5) + self:halign(0) + self:settext("") + self:queuecommand("Set") + end, + SetCommand = function(self) + self:settext(filterFields["Upper"][i]) + end + } + + } + + return r +end + +t[#t+1] = LoadActor("../_mouse") + +t[#t+1] = LoadActor("../_frame") + +-- The top left container (The Info Section) +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(10,30) + end, + + Def.Quad { + InitCommand = function (self) + self:zoomto(leftSectionWidth,leftUpperSectionHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end, + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("General Information") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(5, 75) + self:zoom(0.35) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + local finalString = "Searching:\nSearch by clicking the sort in the top right or by pressing Ctrl + 4\nPress Start or Back to stop typing\nSupports clipboard" + finalString = finalString .. "\n\nFiltering:\nEnter numbers only. The boxes create a range if both are filled" + finalString = finalString .. "\n\nTagging:\nLeft click a Tag to enable or disable filtering\nRight click a Tag to delete it permanently" + self:settext(finalString) + end + } + +} + +-- The lower left container (The Filter Menu) +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(10,30 + leftUpperSectionHeight + verticalSpacing) + end, + + Def.Quad { + InitCommand = function (self) + self:zoomto(leftSectionWidth,leftLowerSectionHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end, + }, + Def.Quad { + InitCommand = function(self) + boundSection = self + self:xy(10 + numBoxWidth,42) + self:zoomto(numBoxWidth * 2 + boundHorizontalSpacing, boxHeight * (#ms.SkillSets+1) + boundVerticalSpacing * #ms.SkillSets) + self:halign(0):valign(0) + self:diffusealpha(0) + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Filter Files") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(20 + numBoxWidth,35) + self:halign(0) + self:zoom(0.3) + self:settext("Lower Bound") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(20 + numBoxWidth*2 + boundHorizontalSpacing,35) + self:halign(0) + self:zoom(0.3) + self:settext("Upper Bound") + end + }, + quadButton(6) .. { + Name = "ApplyButton", + InitCommand = function(self) + self:xy(leftSectionWidth - numBoxWidth - boundHorizontalSpacing, 20) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(numBoxWidth, 20) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + updateFilter() + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(leftSectionWidth - (numBoxWidth + boundHorizontalSpacing)/2 - 5, 20) + self:zoom(0.4) + self:settext("Apply") + end + }, + quadButton(6) .. { + Name = "ResetButton", + InitCommand = function(self) + self:xy(leftSectionWidth - numBoxWidth - boundHorizontalSpacing, 50) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(numBoxWidth, 20) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + resetFilter() + updateEverything() + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(leftSectionWidth - (numBoxWidth + boundHorizontalSpacing)/2 - 5, 50) + self:zoom(0.4) + self:settext("Reset") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(leftSectionWidth - (numBoxWidth + boundHorizontalSpacing)/2 - 15, boxHeight * (#ms.SkillSets+1) + boundVerticalSpacing * #ms.SkillSets) + self:settext("Matches") + self:zoom(0.4) + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(leftSectionWidth - (numBoxWidth + boundHorizontalSpacing)/2 - 15, boxHeight * (#ms.SkillSets+1) + boundVerticalSpacing * #ms.SkillSets + 10) + self:settext("?? / ??") + self:zoom(0.35) + end, + FilterResultsMessageCommand = function(self, msg) + self:settextf("%d / %d", msg.Matches, msg.Total) + end + }, + quadButton(6) .. { + Name = "ModeButton", + InitCommand = function(self) + self:xy(20, 45 + (boxHeight + boundVerticalSpacing)*(#ms.SkillSets+1)) + self:zoomto(numBoxWidth, 20) + self:diffusealpha(0.2) + self:halign(0):valign(0) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + FILTERMAN:ToggleFilterMode() + self:GetParent():queuecommand("Set") + wheelSearch() + end + }, + LoadFont("Common Normal") .. { + Name = "ModeText", + InitCommand = function(self) + self:xy(20 + numBoxWidth/10, 50 + (boxHeight + boundVerticalSpacing)*(#ms.SkillSets+1)) + self:zoom(0.4) + self:valign(0):halign(0) + self:queuecommand("Set") + end, + SetCommand = function(self) + if FILTERMAN:GetFilterMode() then + self:settext("Mode: And") + else + self:settext("Mode: Or") + end + end + }, + LoadFont("Common Normal") .. { + Name = "ModeExplanation", + InitCommand = function(self) + self:xy(20 + numBoxWidth + 5, 50 + (boxHeight + boundVerticalSpacing)*(#ms.SkillSets+1)) + self:zoom(0.4) + self:valign(0):halign(0) + self:queuecommand("Set") + end, + SetCommand = function(self) + if FILTERMAN:GetFilterMode() then + self:settext("Must match all set bounds") + else + self:settext("May match any set bound") + end + end + }, + quadButton(6) .. { + Name = "ApplyButton", + InitCommand = function(self) + packlistFiltered = FILTERMAN:GetFilteringCommonPacks() + self:xy(leftSectionWidth - numBoxWidth - boundHorizontalSpacing, leftLowerSectionHeight - boxHeight - 5) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(numBoxWidth, 20) + self:visible( IsNetSMOnline() and IsSMOnlineLoggedIn(PLAYER_1) and NSMAN:IsETTP() ) + end, + TopPressedCommand = function(self) + if IsNetSMOnline() and IsSMOnlineLoggedIn(PLAYER_1) and NSMAN:IsETTP() then + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + --updateFilter() + packlistFiltered = GHETTOGAMESTATE:getMusicWheel():SetPackListFiltering(not packlistFiltered) + MESSAGEMAN:Broadcast("FilterModeChanged") + end + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(leftSectionWidth - (numBoxWidth + boundHorizontalSpacing)/2 - 5, leftLowerSectionHeight - boxHeight - 5) + self:zoom(0.4) + if IsNetSMOnline() and IsSMOnlineLoggedIn(PLAYER_1) and NSMAN:IsETTP() then + self:playcommand("Set") + else + self:visible(false) + end + end, + SetCommand = function(self) + self:settext(packlistFiltered and "On" or "Off") + end, + FilterModeChangedMessageCommand = function(self) + self:queuecommand("Set") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(leftSectionWidth - (numBoxWidth + boundHorizontalSpacing)/2 - 5, leftLowerSectionHeight - boxHeight*2 - 7) + self:zoom(0.4) + if IsNetSMOnline() and IsSMOnlineLoggedIn(PLAYER_1) and NSMAN:IsETTP() then + self:playcommand("Set") + else + self:visible(false) + end + end, + SetCommand = function(self) + self:settext("Common Pack\nFilter") + end + }, +} + +for i = 1, #filterFields["Lower"] do + t[#t+1] = boundBoxes(i) +end + + +-- The right container (The Tags Menu) +local function rightContainer() + + local boxHeight = 25 + local boxWidth = rightSectionWidth / 3 + + local t = Def.ActorFrame { + InitCommand = function(self) + self:xy(20 + leftSectionWidth,30) + updateTagsFromData() + MESSAGEMAN:Broadcast("UpdateList") + end, + SaveNewTagCommand = function(self) + if tagName ~= "" and ptags[tagName] == nil then + tags:get_data().playerTags[tagName] = {} + tags:set_dirty() + tags:save() + updateTagsFromData() + MESSAGEMAN:Broadcast("UpdateList") + end + end, + + -- The container quad + Def.Quad { + InitCommand = function (self) + self:zoomto(rightSectionWidth,rightSectionHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() then + movePage(1) + end + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Manage Tags") + end + }, + quadButton(6) .. { + InitCommand = function(self) + self:xy(25, rightSectionHeight - 30) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(numBoxWidth + 15, 35) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + local tagname = function(ans) + tagName = ans + self:GetParent():queuecommand("SaveNewTag") + end + easyInputStringWithFunction("Tag Name:", 255, false, tagname) + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(25 + (numBoxWidth+15)/2,rightSectionHeight - 30) + self:zoom(0.4) + self:settext("Create Tag") + end + }, + quadButton(6) .. { + InitCommand = function(self) + self:xy(25 + horizontalSpacing + numBoxWidth + 15, rightSectionHeight - 30) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(numBoxWidth + 15, 35) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + filterTags = {} + updateTagFilter() + updateTagsFromData() + MESSAGEMAN:Broadcast("UpdateList") + end + }, + LoadFont("Common Normal") .. { + Name = "TagModeButtonText", + InitCommand = function(self) + self:xy(25 + horizontalSpacing + numBoxWidth + 15 + (numBoxWidth+15)/2,rightSectionHeight - 30) + self:zoom(0.4) + self:settext("Reset\nTag Filter") + end + }, + quadButton(6) .. { + InitCommand = function(self) + self:xy(25 + horizontalSpacing*2 + (numBoxWidth + 15)*2, rightSectionHeight - 30) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(numBoxWidth + 15, 35) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + if tagFilterMode then + tagFilterMode = false + GHETTOGAMESTATE:setTagFilterMode(false) + else + tagFilterMode = true + GHETTOGAMESTATE:setTagFilterMode(true) + end + self:GetParent():queuecommand("Set") + end + }, + LoadFont("Common Normal") .. { + Name = "TagModeButtonText", + InitCommand = function(self) + self:xy(25 + horizontalSpacing*2 + (numBoxWidth + 15)*2 + (numBoxWidth+15)/2,rightSectionHeight - 30) + self:zoom(0.4) + self:queuecommand("Set") + end, + SetCommand = function(self) + if tagFilterMode then + self:settext("Mode: And") + else + self:settext("Mode: Or") + end + end + }, + LoadFont("Common Normal") .. { + Name = "TagModeExplanation", + InitCommand = function(self) + self:xy(25 + horizontalSpacing*3 + (numBoxWidth + 15)*3, rightSectionHeight - 30) + self:zoom(0.4) + self:halign(0) + self:queuecommand("Set") + self:maxwidth(numBoxWidth * 5) + end, + SetCommand = function(self) + if tagFilterMode then + self:settext("Matches have all chosen Tags") + else + self:settext("Matches have any chosen Tag") + end + end + } + } + + -- this is copied straight from the pack downloader screen + -- theming is so easy lol + local function tagItem(i) + local tagIndex = (curPage-1)*20+i + + local r = Def.ActorFrame{ + InitCommand = function(self) + self:diffusealpha(0) + self:xy(25 + boxWidth*1.5*((tagIndex-1) % maxTags >= 10 and 1 or 0), 30 + ((i-1) % math.floor(maxTags/2))*(boxHeight+verticalSpacing)-10) + if playertags[tagIndex] then + self:playcommand("Show") + end + end, + ShowCommand = function(self) + self:y(30 + ((i-1) % math.floor(maxTags/2))*(boxHeight+verticalSpacing)-10) + self:diffusealpha(0) + self:finishtweening() + self:sleep((i-1)*0.03) + self:easeOut(1) + self:y(30 + ((i-1) % math.floor(maxTags/2))*(boxHeight+verticalSpacing)+25) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:finishtweening() + self:easeOut(0.5) + self:diffusealpha(0) + end, + UpdateListMessageCommand = function(self) + tagIndex = (curPage-1)*20+i + if playertags[tagIndex] ~= nil then + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end + } + + -- Tag index number + r[#r+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(-10,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + end, + SetCommand = function(self) + self:settextf("%d", tagIndex) + end + } + + -- The tag button + r[#r+1] = quadButton(6) .. { + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(boxWidth, boxHeight) + end, + TopPressedCommand = function(self, params) + if playertags[tagIndex] ~= nil then + self:finishtweening() + if params.input == "DeviceButton_left mouse button" then + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + if filterTags[playertags[tagIndex]] then + filterTags[playertags[tagIndex]] = nil + else + filterTags[playertags[tagIndex]] = 1 + end + updateTagFilter() + self:GetParent():GetChild("Status"):queuecommand("Set") + elseif params.input == "DeviceButton_right mouse button" then + tags:get_data().playerTags[playertags[tagIndex]] = nil + playertags[tagIndex] = nil + tags:set_dirty() + tags:save() + updateTagsFromData() + MESSAGEMAN:Broadcast("UpdateList") + end + end + end + } + + -- Tag name + r[#r+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(10,0):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + self:settextf("%s",playertags[tagIndex]) + self:maxwidth(boxWidth * 2) + end + } + + -- Color for the button to show filter status + r[#r+1] = Def.Quad{ + Name = "Status", + InitCommand = function(self) + self:halign(0) + self:diffuse(color(colorConfig:get_data().main.highlight)) + self:diffusealpha(0.8) + self:xy(0, 0) + self:zoomto(4, boxHeight) + end, + SetCommand = function(self) + if filterTags[playertags[tagIndex]] then + self:diffuse(getMiscColor("TagPositive")):diffusealpha(0.8) + else + self:diffuse(getMiscColor("TagNegative")):diffusealpha(0.8) + end + end + } + + return r + end + + for i = 1, maxTags do + t[#t+1] = tagItem(i) + end + + return t +end + +t[#t+1] = rightContainer() + +t[#t+1] = LoadActor("../_cursor") + +return t diff --git a/BGAnimations/ScreenFiltering underlay/default.lua b/BGAnimations/ScreenFiltering underlay/default.lua new file mode 100644 index 00000000..c7a31b85 --- /dev/null +++ b/BGAnimations/ScreenFiltering underlay/default.lua @@ -0,0 +1,10 @@ +local t = Def.ActorFrame{} + +t[#t+1] = Def.Quad { + InitCommand = function(self) + self:diffusealpha(0.8) + self:FullScreen() + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenGameplay failed.lua b/BGAnimations/ScreenGameplay failed.lua index cf4d6a58..f2def555 100644 --- a/BGAnimations/ScreenGameplay failed.lua +++ b/BGAnimations/ScreenGameplay failed.lua @@ -2,12 +2,12 @@ local t = Def.ActorFrame{ InitCommand = function(self) self:diffusealpha(0) self:diffuse(getMainColor("negative")) - end; + end, OffCommand = function(self) self:smooth(1) self:diffusealpha(1) self:sleep(1) - end; + end } t[#t+1] = LoadActor("_background") @@ -20,13 +20,13 @@ t[#t+1] = Def.Quad{ self:smooth(1) self:diffuse(getMainColor("frame")) self:diffusealpha(0.8) - end; + end, OffCommand = function(self) self:sleep(1) self:smooth(1) self:diffusealpha(0) end -}; +} t[#t+1] = LoadFont("Common Normal")..{ InitCommand = function(self) @@ -38,12 +38,12 @@ t[#t+1] = LoadFont("Common Normal")..{ self:diffusealpha(0.8) self:diffuseshift() self:effectcolor1(color("#FFFFFF")):effectcolor2(getMainColor("negative")) - end; + end, OffCommand = function(self) self:sleep(1) self:smooth(1) self:diffusealpha(0) end -}; +} return t \ No newline at end of file diff --git a/BGAnimations/ScreenGameplay out.lua b/BGAnimations/ScreenGameplay out.lua index 038a55bc..8dea4cc5 100644 --- a/BGAnimations/ScreenGameplay out.lua +++ b/BGAnimations/ScreenGameplay out.lua @@ -1,13 +1,13 @@ local t = Def.ActorFrame{ InitCommand = function(self) self:diffusealpha(0) - end; + end, OffCommand = function(self) self:sleep(3) self:smooth(1) self:diffusealpha(1) self:sleep(1) - end; + end } t[#t+1] = LoadActor("_background") @@ -20,13 +20,13 @@ t[#t+1] = Def.Quad{ self:smooth(1) self:diffuse(getMainColor("frame")) self:diffusealpha(0.8) - end; + end, OffCommand = function(self) self:sleep(4) self:smooth(1) self:diffusealpha(0) end -}; +} t[#t+1] = LoadFont("Common Normal")..{ InitCommand = function(self) @@ -38,12 +38,12 @@ t[#t+1] = LoadFont("Common Normal")..{ self:diffusealpha(0.8) self:diffuseshift() self:effectcolor1(color("#FFFFFF")):effectcolor2(getMainColor("positive")) - end; + end, OffCommand = function(self) self:sleep(4) self:smooth(1) self:diffusealpha(0) end -}; +} return t \ No newline at end of file diff --git a/BGAnimations/ScreenGameplay overlay/WifeJudgmentSpotting.lua b/BGAnimations/ScreenGameplay overlay/WifeJudgmentSpotting.lua new file mode 100644 index 00000000..7f76873a --- /dev/null +++ b/BGAnimations/ScreenGameplay overlay/WifeJudgmentSpotting.lua @@ -0,0 +1,789 @@ +--[[ + Basically rewriting the c++ code to not be total shit so this can also not be total shit. +]] +local allowedCustomization = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay +local practiceMode = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingPractice() +local jcKeys = tableKeys(colorConfig:get_data().judgment) +local jcT = {} -- A "T" following a variable name will designate an object of type table. + +for i = 1, #jcKeys do + jcT[jcKeys[i]] = byJudgment(jcKeys[i]) +end + +local jdgT = { + -- Table of judgments for the judgecounter + "TapNoteScore_W1", + "TapNoteScore_W2", + "TapNoteScore_W3", + "TapNoteScore_W4", + "TapNoteScore_W5", + "TapNoteScore_Miss", + "HoldNoteScore_Held", + "HoldNoteScore_LetGo" +} + +local dvCur +local jdgCur -- Note: only for judgments with OFFSETS, might reorganize a bit later +local tDiff +local wifey +local judgect +local pbtarget +local positive = getMainColor("positive") +local highlight = getMainColor("highlight") +local negative = getMainColor("negative") + +local jdgCounts = {} -- Child references for the judge counter + +-- We can also pull in some localized aliases for workhorse functions for a modest speed increase +local Round = notShit.round +local Floor = notShit.floor +local diffusealpha = Actor.diffusealpha +local diffuse = Actor.diffuse +local finishtweening = Actor.finishtweening +local linear = Actor.linear +local x = Actor.x +local y = Actor.y +local addx = Actor.addx +local addy = Actor.addy +local Zoomtoheight = Actor.zoomtoheight +local Zoomtowidth = Actor.zoomtowidth +local Zoomm = Actor.zoom +local queuecommand = Actor.queuecommand +local playcommand = Actor.queuecommand +local settext = BitmapText.settext +local Broadcast = MessageManager.Broadcast + +-- these dont really work as borders since they have to be destroyed/remade in order to scale width/height +-- however we can use these to at least make centered snap lines for the screens -mina +local function dot(height, x) + return Def.Quad { + InitCommand = function(self) + self:zoomto(dotwidth, height) + self:addx(x) + end + } +end + +local function dottedline(len, height, x, y, rot) + local t = + Def.ActorFrame { + InitCommand = function(self) + self:xy(x, y):addrotationz(rot) + if x == 0 and y == 0 then + self:diffusealpha(0.65) + end + end + } + local numdots = len / dotwidth + t[#t + 1] = dot(height, 0) + for i = 1, numdots / 4 do + t[#t + 1] = dot(height, i * dotwidth * 2 - dotwidth / 2) + end + for i = 1, numdots / 4 do + t[#t + 1] = dot(height, -i * dotwidth * 2 + dotwidth / 2) + end + return t +end + +local function DottedBorder(width, height, bw, x, y) + return Def.ActorFrame { + Name = "Border", + InitCommand = function(self) + self:xy(x, y):visible(false):diffusealpha(0.35) + end, + dottedline(width, bw, 0, 0, 0), + dottedline(width, bw, 0, height / 2, 0), + dottedline(width, bw, 0, -height / 2, 0), + dottedline(height, bw, 0, 0, 90), + dottedline(height, bw, width / 2, 0, 90), + dottedline(height, bw, -width / 2, 0, 90) + } +end + +-- Screenwide params +--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==-- +isCentered = PREFSMAN:GetPreference("Center1Player") +local CenterX = SCREEN_CENTER_X +local mpOffset = 0 +if not isCentered then + CenterX = + THEME:GetMetric( + "ScreenGameplay", + string.format("PlayerP1%sX", ToEnumShortString(GAMESTATE:GetCurrentStyle():GetStyleType())) + ) + mpOffset = SCREEN_CENTER_X +end +--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==-- + +local screen -- the screen after it is loaded + +local WIDESCREENWHY = -5 +local WIDESCREENWHX = -5 + +--error bar things +local errorBarFrameWidth = capWideScale(get43size(MovableValues.ErrorBarWidth), MovableValues.ErrorBarWidth) +local wscale = errorBarFrameWidth / 180 + +--differential tracker things +local targetTrackerMode = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).TargetTrackerMode + +--receptor/Notefield things +local Notefield +local noteColumns +local usingReverse + +--guess checking if things are enabled before changing them is good for not having a log full of errors +local enabledErrorBar = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).ErrorBar +local enabledTargetTracker = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).TargetTracker +local enabledDisplayPercent = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).DisplayPercent +local leaderboardEnabled = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).leaderboardEnabled and DLMAN:IsLoggedIn() +local isReplay = GAMESTATE:GetPlayerState(PLAYER_1):GetPlayerController() == "PlayerController_Replay" + +local function arbitraryErrorBarValue(value) + errorBarFrameWidth = capWideScale(get43size(value), value) + wscale = errorBarFrameWidth / 180 +end + +--[[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + **Wife deviance tracker. Basically half the point of the theme.** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + For every doot there is an equal and opposite scoot. +]] +local t = + Def.ActorFrame { + Name = "WifePerch", + OnCommand = function(self) + if allowedCustomization then + -- auto enable autoplay + GAMESTATE:SetAutoplay(true) + else + GAMESTATE:SetAutoplay(false) + end + -- Discord thingies + local largeImageTooltip = + GetPlayerOrMachineProfile(PLAYER_1):GetDisplayName() .. + ": " .. string.format("%5.2f", GetPlayerOrMachineProfile(PLAYER_1):GetPlayerRating()) + local detail = + GAMESTATE:GetCurrentSong():GetDisplayMainTitle() .. + " " .. + string.gsub(getCurRateDisplayString(), "Music", "") .. " [" .. GAMESTATE:GetCurrentSong():GetGroupName() .. "]" + -- truncated to 128 characters(discord hard limit) + detail = #detail < 128 and detail or string.sub(detail, 1, 124) .. "..." + local state = "MSD: " .. string.format("%05.2f", GAMESTATE:GetCurrentSteps(PLAYER_1):GetMSD(getCurRateValue(), 1)) + local endTime = os.time() + GetPlayableTime() + GAMESTATE:UpdateDiscordPresence(largeImageTooltip, detail, state, endTime) + + screen = SCREENMAN:GetTopScreen() + usingReverse = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingReverse() + Notefield = screen:GetChild("PlayerP1"):GetChild("NoteField") + Notefield:addy(MovableValues.NotefieldY * (usingReverse and 1 or -1)) + Notefield:addx(MovableValues.NotefieldX) + noteColumns = Notefield:get_column_actors() + -- lifebar stuff + local lifebar = SCREENMAN:GetTopScreen():GetLifeMeter(PLAYER_1) + + if (allowedCustomization) then + Movable.pressed = false + Movable.current = "None" + Movable.DeviceButton_r.element = Notefield + Movable.DeviceButton_t.element = noteColumns + Movable.DeviceButton_r.condition = true + Movable.DeviceButton_t.condition = true + end + + lifebar:zoomtowidth(MovableValues.PlayerInfoP1Width) + lifebar:zoomtoheight(MovableValues.PlayerInfoP1Height) + lifebar:xy(MovableValues.PlayerInfoP1X, MovableValues.PlayerInfoP1Y) + + for i, actor in ipairs(noteColumns) do + actor:zoomtowidth(MovableValues.NotefieldWidth) + actor:zoomtoheight(MovableValues.NotefieldHeight) + end + end, + DoneLoadingNextSongMessageCommand = function(self) + -- put notefield y pos back on doneloadingnextsong because playlist courses reset this for w.e reason -mina + screen = SCREENMAN:GetTopScreen() + + -- nil checks are needed because these don't exist when doneloadingnextsong is sent initially + -- which is convenient for us since addy -mina + if screen ~= nil and screen:GetChild("PlayerP1") ~= nil then + Notefield = screen:GetChild("PlayerP1"):GetChild("NoteField") + Notefield:addy(MovableValues.NotefieldY * (usingReverse and 1 or -1)) + end + end, + JudgmentMessageCommand = function(self, msg) + tDiff = msg.WifeDifferential + wifey = Floor(msg.WifePercent * 100) / 100 + jdgct = msg.Val + if msg.Offset ~= nil then + dvCur = msg.Offset + else + dvCur = nil + end + if msg.WifePBGoal ~= nil and targetTrackerMode ~= 0 then + pbtarget = msg.WifePBGoal + tDiff = msg.WifePBDifferential + end + jdgCur = msg.Judgment + queuecommand(self, "SpottedOffset") + end +} +--[[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + **LaneCover** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Old scwh lanecover back for now. Equivalent to "screencutting" on ffr; essentially hides notes for a fixed distance before they appear +on screen so you can adjust the time arrows display on screen without modifying their spacing from each other. +]] +if playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).LaneCover then + t[#t + 1] = LoadActor("lanecover") +end + +--[[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + **Player Target Differential: Ghost target rewrite, average score gone for now** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Point differential to AA. +]] +-- Mostly clientside now. We set our desired target goal and listen to the results rather than calculating ourselves. +local target = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).TargetGoal +GAMESTATE:GetPlayerState(PLAYER_1):SetTargetGoal(target / 100) + + +-- We can save space by wrapping the personal best and set percent trackers into one function, however +-- this would make the actor needlessly cumbersome and unnecessarily punish those who don't use the +-- personal best tracker (although everything is efficient enough now it probably wouldn't matter) + +-- moved it for better manipulation +local d = + Def.ActorFrame { + Name = "TargetTracker", + InitCommand = function(self) + if (allowedCustomization) then + Movable.DeviceButton_7.element = self + Movable.DeviceButton_8.element = self + Movable.DeviceButton_8.Border = self:GetChild("Border") + Movable.DeviceButton_7.condition = enabledTargetTracker + Movable.DeviceButton_8.condition = enabledTargetTracker + end + self:xy(MovableValues.TargetTrackerX, MovableValues.TargetTrackerY):zoom(MovableValues.TargetTrackerZoom) + end, + MovableBorder(100, 13, 1, 0, 0) +} + +if targetTrackerMode == 0 then -- going for set goals + d[#d + 1] = + LoadFont("Common Normal") .. + { + Name = "PercentDifferential", + InitCommand = function(self) + self:halign(0):valign(1) + if allowedCustomization then + self:settextf("%5.2f (%5.2f%%)", -100, 100) + setBorderAlignment(self:GetParent():GetChild("Border"), 0, 1) + setBorderToText(self:GetParent():GetChild("Border"), self) + end + self:settextf("") + end, + SpottedOffsetCommand = function(self) + if tDiff >= 0 then + diffuse(self, positive) + else + diffuse(self, negative) + end + self:settextf("%5.2f (%5.2f%%)", tDiff, target) + end + } +else -- going for PB + d[#d + 1] = + LoadFont("Common Normal") .. + { + Name = "PBDifferential", + InitCommand = function(self) + self:halign(0):valign(1) + if allowedCustomization then + self:settextf("%5.2f (%5.2f%%)", -100, 100) + setBorderAlignment(self:GetParent():GetChild("Border"), 0, 1) + setBorderToText(self:GetParent():GetChild("Border"), self) + end + self:settextf("") + end, + SpottedOffsetCommand = function(self, msg) + if pbtarget then + if tDiff >= 0 then + diffuse(self, color("#00ff00")) + else + diffuse(self, negative) + end + self:settextf("%5.2f (%5.2f%%)", tDiff, pbtarget * 100) + else + if tDiff >= 0 then + diffuse(self, positive) + else + diffuse(self, negative) + end + self:settextf("%5.2f (%5.2f%%)", tDiff, target) + end + end + } +end + +if enabledTargetTracker then + t[#t + 1] = d +end + +--[[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + **Display Percent** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Displays the current percent for the score. +]] +local cp = + Def.ActorFrame { + Name = "DisplayPercent", + InitCommand = function(self) + if (allowedCustomization) then + Movable.DeviceButton_w.element = self + Movable.DeviceButton_e.element = self + Movable.DeviceButton_w.condition = enabledDisplayPercent + Movable.DeviceButton_e.condition = enabledDisplayPercent + Movable.DeviceButton_w.Border = self:GetChild("Border") + Movable.DeviceButton_e.Border = self:GetChild("Border") + end + self:zoom(MovableValues.DisplayPercentZoom):x(MovableValues.DisplayPercentX):y(MovableValues.DisplayPercentY) + end, + Def.Quad { + InitCommand = function(self) + self:zoomto(60, 13):diffuse(color("0,0,0,0.4")):halign(1):valign(0) + end + }, + -- Displays your current percentage score + LoadFont("Common Large") .. + { + Name = "DisplayPercent", + InitCommand = function(self) + self:zoom(0.3):halign(1):valign(0) + end, + OnCommand = function(self) + if allowedCustomization then + self:settextf("%05.2f%%", 100) + setBorderAlignment(self:GetParent():GetChild("Border"), 1, 0) + setBorderToText(self:GetParent():GetChild("Border"), self) + end + self:settextf("%05.2f%%", 0) + end, + SpottedOffsetCommand = function(self) + self:settextf("%05.2f%%", math.max(0,wifey)) + end + }, + MovableBorder(100, 13, 1, 0, 0) +} + +if enabledDisplayPercent then + t[#t + 1] = cp +end + +--[[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + **Player ErrorBar** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Visual display of deviance MovableValues. +--]] +-- User Parameters +--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==-- +local barcount = 30 -- Number of bars. Older bars will refresh if judgments/barDuration exceeds this value. You don't need more than 40. +local barWidth = 2 -- Width of the ticks. +local barDuration = 0.75 -- Time duration in seconds before the ticks fade out. Doesn't need to be higher than 1. Maybe if you have 300 bars I guess. +--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==-- +local currentbar = 1 -- so we know which error bar we need to update +local ingots = {} -- references to the error bars +local alpha = 0.07 -- ewma alpha +local avg +local lastAvg + +-- Makes the error bars. They position themselves relative to the center of the screen based on your dv and diffuse to your judgement value before disappating or refreshing +-- Should eventually be handled by the game itself to optimize performance +function smeltErrorBar(index) + return Def.Quad { + Name = index, + InitCommand = function(self) + self:xy(MovableValues.ErrorBarX, MovableValues.ErrorBarY):zoomto(barWidth, MovableValues.ErrorBarHeight):diffusealpha( + 0 + ) + end, + UpdateErrorBarCommand = function(self) -- probably a more efficient way to achieve this effect, should test stuff later + finishtweening(self) -- note: it really looks like shit without the fade out + diffusealpha(self, 1) + diffuse(self, jcT[jdgCur]) + x(self, MovableValues.ErrorBarX + dvCur * wscale) + y(self, MovableValues.ErrorBarY) + Zoomtoheight(self, MovableValues.ErrorBarHeight) + linear(self, barDuration) + diffusealpha(self, 0) + end + } +end + +local e = + Def.ActorFrame { + Name = "ErrorBar", + InitCommand = function(self) + if (allowedCustomization) then + Movable.DeviceButton_5.element = self:GetChildren() + Movable.DeviceButton_6.element = self:GetChildren() + Movable.DeviceButton_5.condition = enabledErrorBar ~= 0 + Movable.DeviceButton_6.condition = enabledErrorBar ~= 0 + Movable.DeviceButton_5.Border = self:GetChild("Border") + Movable.DeviceButton_6.Border = self:GetChild("Border") + Movable.DeviceButton_6.DeviceButton_left.arbitraryFunction = arbitraryErrorBarValue + Movable.DeviceButton_6.DeviceButton_right.arbitraryFunction = arbitraryErrorBarValue + end + if enabledErrorBar == 1 then + for i = 1, barcount do -- basically the equivalent of using GetChildren() if it returned unnamed children numerically indexed + ingots[#ingots + 1] = self:GetChild(i) + end + else + avg = 0 + lastAvg = 0 + end + end, + SpottedOffsetCommand = function(self) + if enabledErrorBar == 1 then + if dvCur ~= nil then + currentbar = ((currentbar) % barcount) + 1 + queuecommand(ingots[currentbar], "UpdateErrorBar") -- Update the next bar in the queue + end + end + end, + DootCommand = function(self) + self:RemoveChild("DestroyMe") + self:RemoveChild("DestroyMe2") + + -- basically we need the ewma version to exist inside this actor frame + -- for customize gameplay stuff, however it seems silly to have it running + -- visibility/nil/type checks if we aren't using it, so we can just remove + -- it if we're outside customize gameplay and errorbar is set to normal -mina + if not allowedCustomization and enabledErrorBar == 1 then + self:RemoveChild("WeightedBar") + end + end, + Def.Quad { + Name = "WeightedBar", + InitCommand = function(self) + if enabledErrorBar == 2 then + self:xy(MovableValues.ErrorBarX, MovableValues.ErrorBarY):zoomto(barWidth, MovableValues.ErrorBarHeight):diffusealpha( + 1 + ):diffuse(getMainColor("enabled")) + else + self:visible(false) + end + end, + SpottedOffsetCommand = function(self) + if enabledErrorBar == 2 and dvCur ~= nil then + avg = alpha * dvCur + (1 - alpha) * lastAvg + lastAvg = avg + self:x(MovableValues.ErrorBarX + avg * wscale) + end + end + }, + Def.Quad { + Name = "Center", + InitCommand = function(self) + self:diffuse(getMainColor("highlight")):xy(MovableValues.ErrorBarX, MovableValues.ErrorBarY):zoomto( + 2, + MovableValues.ErrorBarHeight + ) + end + }, + -- Indicates which side is which (early/late) These should be destroyed after the song starts. + LoadFont("Common Normal") .. + { + Name = "DestroyMe", + InitCommand = function(self) + self:xy(MovableValues.ErrorBarX + errorBarFrameWidth / 4, MovableValues.ErrorBarY):zoom(0.35) + end, + BeginCommand = function(self) + self:settext("Late"):diffusealpha(0):smooth(0.5):diffusealpha(0.5):sleep(1.5):smooth(0.5):diffusealpha(0) + end + }, + LoadFont("Common Normal") .. + { + Name = "DestroyMe2", + InitCommand = function(self) + self:xy(MovableValues.ErrorBarX - errorBarFrameWidth / 4, MovableValues.ErrorBarY):zoom(0.35) + end, + BeginCommand = function(self) + self:settext("Early"):diffusealpha(0):smooth(0.5):diffusealpha(0.5):sleep(1.5):smooth(0.5):diffusealpha(0):queuecommand( + "Doot" + ) + end, + DootCommand = function(self) + self:GetParent():queuecommand("Doot") + end + }, + MovableBorder( + MovableValues.ErrorBarWidth, + MovableValues.ErrorBarHeight, + 1, + MovableValues.ErrorBarX, + MovableValues.ErrorBarY + ) +} + +-- Initialize bars +if enabledErrorBar == 1 then + for i = 1, barcount do + e[#e + 1] = smeltErrorBar(i) + end +end + +-- Add the completed errorbar frame to the primary actor frame t if enabled +if enabledErrorBar ~= 0 then + t[#t + 1] = e +end + +--[[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + **Music Rate Display** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +]] +t[#t + 1] = + LoadFont("Common Normal") .. + { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, SCREEN_BOTTOM - 20):zoom(0.35):settext(getCurRateDisplayString()) + end, + SetRateCommand = function(self) + self:settext(getCurRateDisplayString()) + end, + DoneLoadingNextSongMessageCommand = function(self) + self:playcommand("SetRate") + end, + CurrentRateChangedMessageCommand = function(self) + self:playcommand("SetRate") + end + } + +--[[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + **BPM Display** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Better optimized frame update bpm display. +]] +local BPM +local a = GAMESTATE:GetPlayerState(PLAYER_1):GetSongPosition() +local r = GAMESTATE:GetSongOptionsObject("ModsLevel_Current"):MusicRate() * 60 +local GetBPS = SongPosition.GetCurBPS + +local function UpdateBPM(self) + local bpm = GetBPS(a) * r + settext(BPM, Round(bpm, 2)) +end + +t[#t + 1] = + Def.ActorFrame { + InitCommand = function(self) + BPM = self:GetChild("BPM") + if #GAMESTATE:GetCurrentSong():GetTimingData():GetBPMs() > 1 then -- dont bother updating for single bpm files + self:SetUpdateFunction(UpdateBPM) + self:SetUpdateRate(0.5) + else + BPM:settextf("%5.2f", GetBPS(a) * r) -- i wasn't thinking when i did this, we don't need to avoid formatting for performance because we only call this once -mina + end + end, + LoadFont("Common Normal") .. + { + Name = "BPM", + InitCommand = function(self) + self:x(SCREEN_CENTER_X):y(SCREEN_BOTTOM - 30):halign(0.5):zoom(0.40) + end + }, + DoneLoadingNextSongMessageCommand = function(self) + self:queuecommand("Init") + end, + -- basically a copy of the init + CurrentRateChangedMessageCommand = function(self) + r = GAMESTATE:GetSongOptionsObject("ModsLevel_Current"):MusicRate() * 60 + if #GAMESTATE:GetCurrentSong():GetTimingData():GetBPMs() > 1 then + self:SetUpdateFunction(UpdateBPM) + self:SetUpdateRate(0.5) + else + BPM:settextf("%5.2f", GetBPS(a) * r) + end + end +} + +--[[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + **Combo Display** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +]] +local x = 0 +local y = 60 + +-- CUZ WIDESCREEN DEFAULTS SCREAAAAAAAAAAAAAAAAAAAAAAAAAM -mina +if IsUsingWideScreen() then + y = y - WIDESCREENWHY + x = x + WIDESCREENWHX +end + +--This just initializes the initial point or not idk not needed to mess with this any more +function ComboTransformCommand(self, params) + self:x(x) + self:y(y) +end + +--[[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + **Practice Mode** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + stuff +]] +local prevZoom = 0.65 +local musicratio = 1 + +-- hurrrrr nps quadzapalooza -mina +local wodth = capWideScale(get43size(240), 280) +local hidth = 40 +local cd +local bookmarkPosition + +local function duminput(event) + if event.DeviceInput.button == "DeviceButton_left mouse button" and event.type == "InputEventType_Release" then + MESSAGEMAN:Broadcast("MouseLeftClick") + elseif event.DeviceInput.button == "DeviceButton_right mouse button" and event.type == "InputEventType_Release" then + MESSAGEMAN:Broadcast("MouseRightClick") + elseif event.DeviceInput.button == "DeviceButton_backspace" and event.type == "InputEventType_FirstPress" then + if bookmarkPosition ~= nil then + SCREENMAN:GetTopScreen():SetPreviewNoteFieldMusicPosition(bookmarkPosition) + end + elseif event.button == "EffectUp" and event.type == "InputEventType_FirstPress" then + SCREENMAN:GetTopScreen():AddToPracticeRate(0.05) + elseif event.button == "EffectDown" and event.type == "InputEventType_FirstPress" then + SCREENMAN:GetTopScreen():AddToPracticeRate(-0.05) + end + return false +end + +local function UpdatePreviewPos(self) + local pos = SCREENMAN:GetTopScreen():GetSongPosition() / musicratio + self:GetChild("Pos"):zoomto(math.min(math.max(0, pos), wodth), hidth) + self:queuecommand("Highlight") +end + +local pm = + Def.ActorFrame { + Name = "ChartPreview", + InitCommand = function(self) + self:xy(MovableValues.PracticeCDGraphX, MovableValues.PracticeCDGraphY) + self:SetUpdateFunction(UpdatePreviewPos) + cd = self:GetChild("ChordDensityGraph"):visible(true):draworder(1000):y(20) + if (allowedCustomization) then + Movable.DeviceButton_z.element = self + Movable.DeviceButton_z.condition = practiceMode + --Movable.DeviceButton_z.Border = self:GetChild("Border") + --Movable.DeviceButton_x.element = self + --Movable.DeviceButton_x.condition = practiceMode + --Movable.DeviceButton_x.Border = self:GetChild("Border") + end + --self:zoomto(MovableValues.PracticeCDGraphWidth, MovableValues.PracticeCDGraphHeight) + end, + BeginCommand = function(self) + musicratio = GAMESTATE:GetCurrentSong():GetLastSecond() / (wodth) + SCREENMAN:GetTopScreen():AddInputCallback(duminput) + cd:GetChild("cdbg"):diffusealpha(0) + self:SortByDrawOrder() + self:queuecommand("GraphUpdate") + end, + Def.Quad { + Name = "BG", + InitCommand = function(self) + self:x(wodth / 2) + self:diffuse(color("0.05,0.05,0.05,1")) + end + }, + Def.Quad { + Name = "PosBG", + InitCommand = function(self) + self:zoomto(wodth, hidth):halign(0):diffuse(color("1,1,1,1")):draworder(900) + end, + HighlightCommand = function(self) -- use the bg for detection but move the seek pointer -mina + if isOver(self) then + self:GetParent():GetChild("Seek"):visible(true) + self:GetParent():GetChild("Seektext"):visible(true) + self:GetParent():GetChild("Seek"):x(INPUTFILTER:GetMouseX() - self:GetParent():GetX()) + self:GetParent():GetChild("Seektext"):x(INPUTFILTER:GetMouseX() - self:GetParent():GetX() - 4) -- todo: refactor this lmao -mina + self:GetParent():GetChild("Seektext"):y(INPUTFILTER:GetMouseY() - self:GetParent():GetY()) + self:GetParent():GetChild("Seektext"):settextf( + "%0.2f", + self:GetParent():GetChild("Seek"):GetX() * musicratio / getCurRateValue() + ) + else + self:GetParent():GetChild("Seektext"):visible(false) + self:GetParent():GetChild("Seek"):visible(false) + end + end + }, + Def.Quad { + Name = "Pos", + InitCommand = function(self) + self:zoomto(0, hidth):diffuse(color("0,1,0,.5")):halign(0):draworder(900) + end + } + --MovableBorder(wodth+3, hidth+3, 1, (wodth)/2, 0) +} + +-- Load the CDGraph with a forced width parameter. +pm[#pm + 1] = LoadActorWithParams("../_gameplaydensitygraph.lua", {width=wodth}) + +-- more draw order shenanigans +pm[#pm + 1] = + LoadFont("Common Normal") .. + { + Name = "Seektext", + InitCommand = function(self) + self:y(8):valign(1):halign(1):draworder(1100):diffuse(color("0.8,0,0")):zoom(0.4) + end + } + +pm[#pm + 1] = + Def.Quad { + Name = "Seek", + InitCommand = function(self) + self:zoomto(2, hidth):diffuse(color("1,.2,.5,1")):halign(0.5):draworder(1100) + end, + MouseLeftClickMessageCommand = function(self) + if isOver(self) then + SCREENMAN:GetTopScreen():SetPreviewNoteFieldMusicPosition(self:GetX() * musicratio) + end + end, + MouseRightClickMessageCommand = function(self) + if isOver(self) then + bookmarkPosition = self:GetX() * musicratio + self:GetParent():GetChild("BookmarkPos"):queuecommand("Set") + else + if not (allowedCustomization) then + SCREENMAN:GetTopScreen():TogglePracticePause() + end + end + end +} + +pm[#pm + 1] = + Def.Quad { + Name = "BookmarkPos", + InitCommand = function(self) + self:zoomto(2, hidth):diffuse(color(".2,.5,1,1")):halign(0.5):draworder(1100) + self:visible(false) + end, + SetCommand = function(self) + self:visible(true) + self:x(bookmarkPosition / musicratio) + end +} + +if practiceMode and not isReplay then + t[#t + 1] = pm +end + + +return t diff --git a/BGAnimations/ScreenGameplay overlay/avatar.lua b/BGAnimations/ScreenGameplay overlay/avatar.lua index cf101e14..b10d8ea8 100644 --- a/BGAnimations/ScreenGameplay overlay/avatar.lua +++ b/BGAnimations/ScreenGameplay overlay/avatar.lua @@ -1,207 +1,198 @@ +local allowedCustomization = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay +local fullPlayerInfo = themeConfig:get_data().global.PlayerInfoType -- true for full, false for minimal (lifebar only) --Avatar frames which also includes current additive %score, mods, and the song stepsttype/difficulty. - -local t = Def.ActorFrame{ - Name="Avatars"; -}; - -local bareBone = isBareBone() - local profileP1 -local profileP2 local profileNameP1 = "No Profile" -local profileNameP2 = "No Profile" local avatarPosition = { - PlayerNumber_P1 = { - X = 10, - Y = 10 - }, - PlayerNumber_P2 = { - X = SCREEN_WIDTH-60, - Y = 10 - } + X = MovableValues.PlayerInfoP1X, + Y = MovableValues.PlayerInfoP1Y } local function PLife(pn) - return STATSMAN:GetCurStageStats():GetPlayerStageStats(pn):GetCurrentLife() or 0 -end; - -local function avatarFrame(pn) - local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(pn) + local life = STATSMAN:GetCurStageStats():GetPlayerStageStats(pn):GetCurrentLife() or 0 + if life < 0 then + return 0 + else + return life + end +end - local t = Def.ActorFrame{ - InitCommand = function(self) - self:xy(avatarPosition[pn].X,avatarPosition[pn].Y) - end; - } - local profile = GetPlayerOrMachineProfile(pn) +local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(PLAYER_1) +local profile = GetPlayerOrMachineProfile(PLAYER_1) + +-- whole frame actorframe +local t = Def.ActorFrame { + OnCommand = function(self) + self:xy(avatarPosition.X,avatarPosition.Y) + self:zoomto(MovableValues.PlayerInfoP1Width, MovableValues.PlayerInfoP1Height) + if (allowedCustomization) then + Movable.DeviceButton_j.element = self + Movable.DeviceButton_j.condition = true + Movable.DeviceButton_k.element = self + Movable.DeviceButton_k.condition = true + end + end, +} +if fullPlayerInfo then + -- whole frame bg quad t[#t+1] = Def.Quad { InitCommand = function(self) - if pn == PLAYER_1 then - self:zoomto(200,50) - self:halign(0):valign(0) - else - self:x(50):zoomto(200,50) - self:halign(1):valign(0) - end + self:zoomto(200,50) + self:halign(0):valign(0) self:queuecommand('Set') - end; + end, SetCommand=function(self) - local steps = GAMESTATE:GetCurrentSteps(pn); + local steps = GAMESTATE:GetCurrentSteps(PLAYER_1) local diff = steps:GetDifficulty() self:diffuse(color("#000000")) self:diffusealpha(0.8) - end; - CurrentSongChangedMessageCommand = function(self) self:queuecommand('Set') end; + end, + CurrentSongChangedMessageCommand = function(self) self:queuecommand('Set') end } + -- border? t[#t+1] = Def.Quad{ InitCommand = function(self) - if pn == PLAYER_1 then - self:zoomto(200,50) - self:halign(0):valign(0) - self:xy(-3,-3) - else - self:xy(53,-3):zoomto(200,50) - self:halign(1):valign(0) - end + self:zoomto(200,50) + self:halign(0):valign(0) + self:xy(-3,-3) self:zoomto(56,56) self:diffuse(color("#000000")) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) self:stoptweening() self:smooth(0.5) self:diffuse(getBorderColor()) - end; - BeginCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end } + -- avatar t[#t+1] = Def.Sprite { InitCommand = function(self) self:halign(0):valign(0) - end; - BeginCommand = function(self) self:queuecommand('ModifyAvatar') end; + end, + BeginCommand = function(self) self:queuecommand('ModifyAvatar') end, ModifyAvatarCommand=function(self) - self:finishtweening(); - self:LoadBackground(PROFILEMAN:GetAvatarPath(pn)); + self:finishtweening() + self:LoadBackground(assetFolders.avatar .. findAvatar(profile:GetGUID())) self:zoomto(50,50) - end; - }; - + end + } + -- profile name t[#t+1] = LoadFont("Common Bold") .. { InitCommand= function(self) local name = profile:GetDisplayName() - if pn == PLAYER_1 then - self:xy(56,12):zoom(0.6):shadowlength(1):halign(0):maxwidth(180/0.6) - else - self:xy(-6,12):zoom(0.6):shadowlength(1):halign(1):maxwidth(180/0.6) - end - self:settext(name) - end; - }; + self:xy(56,7):zoom(0.6):shadowlength(1):halign(0):maxwidth(180/0.6) + self:settext(name) + end + } + -- diff name t[#t+1] = LoadFont("Common Normal") .. { InitCommand = function(self) - if pn == PLAYER_1 then - self:xy(56,26):zoom(0.4):halign(0):maxwidth(180/0.4) - else - self:xy(-6,26):zoom(0.4):halign(1):maxwidth(180/0.4) - end - end; - BeginCommand = function(self) self:queuecommand('Set') end; + self:xy(56,21):zoom(0.4):halign(0):maxwidth(180/0.4) + end, + BeginCommand = function(self) self:queuecommand('Set') end, SetCommand=function(self) - local steps = GAMESTATE:GetCurrentSteps(pn); + local steps = GAMESTATE:GetCurrentSteps(PLAYER_1) local diff = getDifficulty(steps:GetDifficulty()) local meter = steps:GetMSD(getCurRateValue(),1) - meter = meter == 0 and steps:GetMeter() or math.floor(meter) + meter = meter == 0 and steps:GetMeter() or meter local stype = ToEnumShortString(steps:GetStepsType()):gsub("%_"," ") - self:settext(stype.." "..diff.." "..math.floor(meter)) + self:settextf("%s %s %5.2f",stype, diff, meter) self:diffuse(getDifficultyColor(steps:GetDifficulty())) - end; - CurrentSongChangedMessageCommand = function(self) self:queuecommand('Set') end; - }; - - t[#t+1] = Def.Quad{ - InitCommand = function(self) - if pn == PLAYER_1 then - self:zoomto(200,50) - self:halign(0) - self:xy(57, 40) - else - self:xy(-7, 40):zoomto(200,50) - self:halign(1) - end - self:zoomto(120,10) - end; - } - - t[#t+1] = Def.Quad{ - InitCommand = function(self) - if pn == PLAYER_1 then - self:halign(0) - self:xy(57, 40) - else - self:halign(1) - self:xy(-7, 40) - end - self:zoomto(0,10) - self:diffuse(getMainColor("highlight")) - self:queuecommand("Set") - end; - JudgmentMessageCommand = function(self) - self:queuecommand("Set") - end; - SetCommand = function(self) - self:finishtweening() - self:smooth(0.1) - self:zoomx(PLife(pn)*120) - end + end, + CurrentSongChangedMessageCommand = function(self) self:queuecommand('Set') end } + t[#t+1] = LoadFont("Common Bold") .. { OnCommand = function(self) - if pn == PLAYER_1 then - self:xy(57+120+10, 40-1) - else - self:xy(-7-120-10, 40-1) - end + self:xy(57, 47) self:zoom(0.35) self:queuecommand("Set") - end; - JudgmentMessageCommand = function(self) - self:queuecommand("Set") - end; + self:halign(0) + self:maxwidth(200 * 2) + end, SetCommand = function(self) - local life = PLife(pn) - self:settextf("%0.0f",life*100) - if life*100 < 30 and life*100 ~= 0 then -- replace with lifemeter danger later - self:diffuseshift() - self:effectcolor1(1,1,1,1) - self:effectcolor2(1,0.9,0.9,0.5) - self:effectperiod(0.9*life+0.15) - elseif life*100 <= 0 then - self:stopeffect() - self:diffuse(color("0,0,0,1")) - else - self:stopeffect() - self:diffuse(color("1,1,1,1")) - end; + local mods = GAMESTATE:GetPlayerState(PLAYER_1):GetPlayerOptionsString("ModsLevel_Current") + self:settext(mods) end + } +end +-- life bg +t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(200,50) + self:halign(0) + self:xy(57, 35) + self:zoomto(120,10) + end +} - return t -end +-- life bar +t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:halign(0) + self:xy(57, 35) + self:zoomto(0,10) + self:diffuse(getMainColor("highlight")) + self:queuecommand("Set") + end, + JudgmentMessageCommand = function(self, params) + self:playcommand("Set", params) + end, + SetCommand = function(self, params) + if params ~= nil and params.TapNoteScore == "TapNoteScore_AvoidMine" then + return + end + self:finishtweening() + self:smooth(0.1) + self:zoomx(PLife(PLAYER_1)*120) + end +} + +-- life counter +t[#t+1] = LoadFont("Common Bold") .. { + OnCommand = function(self) + self:xy(57+120+10, 35-1) + self:zoom(0.35) + self:queuecommand("Set") + end, + JudgmentMessageCommand = function(self, params) + self:playcommand("Set", params) + end, + SetCommand = function(self, params) + if params ~= nil and params.TapNoteScore == "TapNoteScore_AvoidMine" then + return + end + local life = PLife(PLAYER_1) + self:settextf("%0.0f",life*100) + if life*100 < 30 and life*100 ~= 0 then -- replace with lifemeter danger later + self:diffuseshift() + self:effectcolor1(1,1,1,1) + self:effectcolor2(1,0.9,0.9,0.5) + self:effectperiod(0.9*life+0.15) + elseif life*100 <= 0 then + self:stopeffect() + self:diffuse(color("0,0,0,1")) + else + self:stopeffect() + self:diffuse(color("1,1,1,1")) + end + end +} -for _,pn in pairs(GAMESTATE:GetEnabledPlayers()) do - t[#t+1] = avatarFrame(pn) -end -return t; \ No newline at end of file +return t \ No newline at end of file diff --git a/BGAnimations/ScreenGameplay overlay/bpmdisplay.lua b/BGAnimations/ScreenGameplay overlay/bpmdisplay.lua index d0d80605..cc81b252 100644 --- a/BGAnimations/ScreenGameplay overlay/bpmdisplay.lua +++ b/BGAnimations/ScreenGameplay overlay/bpmdisplay.lua @@ -13,26 +13,14 @@ local t = Def.ActorFrame {} if GAMESTATE:IsPlayerEnabled(PLAYER_1) then t[#t+1] = LoadFont("Common Normal") .. { - Name="Player1BPM"; + Name="Player1BPM", BeginCommand = function(self) self:xy(5,25):halign(0):zoom(0.4) if not bareBone then self:shadowlength(1) end end - }; -end - -if GAMESTATE:IsPlayerEnabled(PLAYER_2) then - t[#t+1] = LoadFont("Common Normal") .. { - Name="Player2BPM"; - BeginCommand = function(self) - self:xy(SCREEN_WIDTH-5,25):halign(1):zoom(0.4) - if not bareBone then - self:shadowlength(1) - end - end - }; + } end -- Updates bpm text. @@ -45,9 +33,6 @@ local function Update(self) self:GetChild("Player1BPM"):settextf("%0.2f BPM",getPlayerBPM(PLAYER_1)) end - if GAMESTATE:IsPlayerEnabled(PLAYER_2) then - self:GetChild("Player2BPM"):settextf("%0.2f BPM",getPlayerBPM(PLAYER_2)) - end end if true then diff --git a/BGAnimations/ScreenGameplay overlay/default.lua b/BGAnimations/ScreenGameplay overlay/default.lua index 6a9ef967..71bbc150 100644 --- a/BGAnimations/ScreenGameplay overlay/default.lua +++ b/BGAnimations/ScreenGameplay overlay/default.lua @@ -1,4 +1,9 @@ -local t = Def.ActorFrame{} +local inCustomize = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay +local inPractice = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingPractice() +local inReplay = GAMESTATE:GetPlayerState(PLAYER_1):GetPlayerController() == "PlayerController_Replay" + +local t = Def.ActorFrame {} + local pn = GAMESTATE:GetEnabledPlayers()[1] local profile = GetPlayerOrMachineProfile(pn) local steps = GAMESTATE:GetCurrentSteps(pn) @@ -10,23 +15,25 @@ t[#t+1] = LoadActor("judgecount") --t[#t+1] = LoadActor("pacemaker") t[#t+1] = LoadActor("npscalc") --t[#t+1] = LoadActor("lifepercent") - t[#t+1] = LoadActor("lanecover") -t[#t+1] = LoadActor("progressbar") -t[#t+1] = LoadActor("errorbar") +t[#t+1] = LoadActor("WifeJudgmentSpotting") +if themeConfig:get_data().global.ProgressBar ~= 0 then + t[#t+1] = LoadActor("progressbar") +end +t[#t+1] = LoadActor("leaderboard") t[#t+1] = LoadActor("avatar") --t[#t+1] = LoadActor("BPMDisplay") t[#t+1] = LoadActor("title") +if inCustomize then + t[#t+1] = LoadActor("messagebox") +end - - -t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:xy(SCREEN_CENTER_X,SCREEN_BOTTOM-10):zoom(0.35):settext(GAMESTATE:GetSongOptions('ModsLevel_Song')):shadowlength(1) - end; -} - +if not inCustomize and not inPractice and not inReplay then + HOOKS:ShowCursor(false) +else + t[#t+1] = LoadActor("../_cursor") +end local largeImageText = string.format("%s: %5.2f",profile:GetDisplayName(), profile:GetPlayerRating()) diff --git a/BGAnimations/ScreenGameplay overlay/errorbar.lua b/BGAnimations/ScreenGameplay overlay/errorbar.lua index f0156be1..ea15e7e8 100644 --- a/BGAnimations/ScreenGameplay overlay/errorbar.lua +++ b/BGAnimations/ScreenGameplay overlay/errorbar.lua @@ -1,8 +1,7 @@ -- A somewhat naive implementation of the osu's error bar. -- Single Player only until I figure out where to put everything -- Hopefully I can change it so I don't have to initialize like 300 quads beforehand. -local enabled = (((playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).ErrorBar == true) and GAMESTATE:IsHumanPlayer(PLAYER_1)) or - ((playerConfig:get_data(pn_to_profile_slot(PLAYER_2)).ErrorBar == true) and GAMESTATE:IsHumanPlayer(PLAYER_2))) and +local enabled = ((playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).ErrorBar == true) and GAMESTATE:IsHumanPlayer(PLAYER_1)) and GAMESTATE:GetNumPlayersEnabled() == 1 local pn = GAMESTATE:GetEnabledPlayers()[1] local bareBone = isBareBone() @@ -32,10 +31,10 @@ local currentbar = 1 -- Index to be updated local function proTimingTicks(pn,index) return Def.Quad{ - Name = tostring(index); + Name = tostring(index), InitCommand = function(self) self:zoomto(tickWidth,frameHeight):diffusealpha(0) - end; + end, UpdateTickCommand = function(self,params) local enumVal = Enum.Reverse(TapNoteScore)[params.TapNoteScore] @@ -63,7 +62,7 @@ if enabled then t[#t+1] = Def.Quad{ InitCommand=function(self) self:zoomto(frameWidth,frameHeight):diffuse(color("#666666")):diffusealpha(backgroundOpacity) - end; + end } for i=1,barcount do @@ -86,30 +85,30 @@ if enabled then t[#t+1] = Def.Quad{ InitCommand=function(self) self:zoomto(2,frameHeight):diffuse(color("#FFFFFF")):diffusealpha(0.5) - end; + end } if not bareBone then t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:x(frameWidth/4):zoom(0.35) - end; + end, BeginCommand=function(self) self:settext("Late"):diffusealpha(0):smooth(0.5):diffusealpha(0.5):sleep(1.5):smooth(0.5):diffusealpha(0) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:x(-frameWidth/4):zoom(0.35) - end; + end, BeginCommand=function(self) self:settext("Early"):diffusealpha(0):smooth(0.5):diffusealpha(0.5):sleep(1.5):smooth(0.5):diffusealpha(0) - end; + end } end -end; +end diff --git a/BGAnimations/ScreenGameplay overlay/judgecount.lua b/BGAnimations/ScreenGameplay overlay/judgecount.lua index aadb7d69..759d7ade 100644 --- a/BGAnimations/ScreenGameplay overlay/judgecount.lua +++ b/BGAnimations/ScreenGameplay overlay/judgecount.lua @@ -16,12 +16,11 @@ for k,v in pairs(judges) do end local bareBone = isBareBone() -local cols = GAMESTATE:GetCurrentStyle():ColumnsPerPlayer(); -- For relocating graph/judgecount frame -local center1P = ((cols >= 6) or PREFSMAN:GetPreference("Center1Player")); -- For relocating graph/judgecount frame +local cols = GAMESTATE:GetCurrentStyle():ColumnsPerPlayer() -- For relocating graph/judgecount frame +local center1P = ((cols >= 6) or PREFSMAN:GetPreference("Center1Player")) -- For relocating graph/judgecount frame local judgeTypeP1 = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).JudgeType -local judgeTypeP2 = playerConfig:get_data(pn_to_profile_slot(PLAYER_2)).JudgeType - +local allowedCustomization = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay local spacing = 12 -- Spacing between the judgetypes local frameWidth = 80 -- Width of the Frame @@ -34,142 +33,127 @@ local backgroundOpacity = bareBone and 1 or 0.6 local position = { PlayerNumber_P1 = { - X = 20, - Y = (SCREEN_HEIGHT*0.62)-5 - }, - PlayerNumber_P2 = { - X = SCREEN_WIDTH-20-frameWidth, - Y = (SCREEN_HEIGHT*0.62)-5 + X = MovableValues.JudgeCounterX, + Y = MovableValues.JudgeCounterY } } --adjust for non-widescreen users. if ((not center1P) and (not IsUsingWideScreen())) then position.PlayerNumber_P1.X = SCREEN_CENTER_X+20 - position.PlayerNumber_P2.X = SCREEN_CENTER_X-20-frameWidth end --- tl;dr: if theres no room, don't show. -local enabled1P = (GAMESTATE:IsPlayerEnabled(PLAYER_1) and judgeTypeP1 ~= 0) and (IsUsingWideScreen() or (GAMESTATE:GetNumPlayersEnabled() == 1 and cols <= 6)) -local enabled2P = (GAMESTATE:IsPlayerEnabled(PLAYER_2) and judgeTypeP2 ~= 0) and (IsUsingWideScreen() or (GAMESTATE:GetNumPlayersEnabled() == 1 and cols <= 6)) - +local enabled1P = judgeTypeP1 ~= 0 +if not enabled1P then + return Def.ActorFrame {} +end --=========================================================================-- --=========================================================================-- --=========================================================================-- -local t = Def.ActorFrame{} - - -- The Judgment text itself (MA for marvelous, etc.) -local function judgeCounter(pn) - local highlight = playerConfig:get_data(pn_to_profile_slot(pn)).JudgeType == 2 and not bareBone - local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(pn) - - local t = Def.ActorFrame{ - InitCommand = function(self) - self:xy(position[pn].X, position[pn].Y) - end; - JudgmentMessageCommand = function(self, params) - if params.Player == pn then - self:GetChild(pn.."Grade"):playcommand("Set", params) - if judges2[params.HoldNoteScore] then - if highlight then - self:GetChild(pn..params.HoldNoteScore.."Highlight"):playcommand("Set") - end - self:GetChild(pn..params.HoldNoteScore.."Count"):queuecommand("Set") - elseif judges2[params.TapNoteScore] then - if highlight then - self:GetChild(pn..params.TapNoteScore.."Highlight"):playcommand("Set") - end - self:GetChild(pn..params.TapNoteScore.."Count"):queuecommand("Set") +local highlight = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).JudgeType == 2 and not bareBone +local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(PLAYER_1) + +local t = Def.ActorFrame { + Name = "JudgeCounter", + InitCommand = function(self) + self:xy(position[PLAYER_1].X, position[PLAYER_1].Y) + if (allowedCustomization) then + Movable.DeviceButton_p.element = self + Movable.DeviceButton_p.condition = enabled1P + end + end, + JudgmentMessageCommand = function(self, params) + if params.Player == PLAYER_1 then + self:GetChild(PLAYER_1.."Grade"):playcommand("Set", params) + if judges2[params.HoldNoteScore] then + if highlight then + self:GetChild(PLAYER_1..params.HoldNoteScore.."Highlight"):playcommand("Set") + end + self:GetChild(PLAYER_1..params.HoldNoteScore.."Count"):queuecommand("Set") + elseif judges2[params.TapNoteScore] then + if highlight then + self:GetChild(PLAYER_1..params.TapNoteScore.."Highlight"):playcommand("Set") end + self:GetChild(PLAYER_1..params.TapNoteScore.."Count"):queuecommand("Set") end - end; - } - - t[#t+1] = Def.Quad{ -- Judgecount Background - InitCommand = function(self) - self:zoomto(frameWidth,frameHeight):halign(0):valign(0) - self:diffuse(getMainColor("frame")):diffusealpha(backgroundOpacity) end - } - - t[#t+1] = LoadFont("Common Bold") .. { --grade - Name=pn.."Grade"; - InitCommand = function(self) - self:xy(5,8+(#judges*spacing)):halign(0) - self:zoom(gradeFontSize) - self:playcommand("Set") - end; - SetCommand = function(self, params) - if not params then - self:settext(getGradeStrings("Grade_Tier07")) - return - end - self:settext(getGradeStrings(getWifeGradeTier(params.WifePercent))) + end, + MovableBorder(frameWidth, frameHeight, 1, frameWidth/2, frameHeight/2) +} - - end; - } +t[#t+1] = Def.Quad{ -- Judgecount Background + InitCommand = function(self) + self:zoomto(frameWidth,frameHeight):halign(0):valign(0) + self:diffuse(getMainColor("frame")):diffusealpha(backgroundOpacity) + end +} - for k,v in ipairs(judges) do - - if highlight then - t[#t+1] = Def.Quad{ --JudgeHighlight - Name=pn..v.."Highlight"; - InitCommand = function(self) - self:xy(0,5+((k-1)*spacing)):zoomto(frameWidth,5):halign(0):valign(0) - self:diffuse(color(colorConfig:get_data().judgment[v])):diffusealpha(0) - end; - SetCommand=function(self) - self:stoptweening() - self:linear(0.1) - self:diffusealpha(highlightOpacity) - self:linear(0.5) - self:diffusealpha(0) - end - } +t[#t+1] = LoadFont("Common Bold") .. { --grade + Name=PLAYER_1.."Grade", + InitCommand = function(self) + self:xy(5,8+(#judges*spacing)):halign(0) + self:zoom(gradeFontSize) + self:playcommand("Set") + end, + SetCommand = function(self, params) + if not params then + self:settext(getGradeStrings("Grade_Tier07")) + return end + self:settext(getGradeStrings(getWifeGradeTier(params.WifePercent))) - t[#t+1] = LoadFont("Common normal")..{ - InitCommand = function(self) - self:xy(5,7+((k-1)*spacing)):zoom(judgeFontSize):halign(0) - if not bareBone then - self:settext(getJudgeStrings(v)) - self:diffuse(color(colorConfig:get_data().judgment[v])) - else - self:settext(getShortJudgeStrings(v)) - end - end; - } + + end +} - t[#t+1] = LoadFont("Common Normal") .. { - Name=pn..v.."Count"; +for k,v in ipairs(judges) do + + if highlight then + t[#t+1] = Def.Quad{ --JudgeHighlight + Name=PLAYER_1..v.."Highlight", InitCommand = function(self) - self:xy(frameWidth-5,7+((k-1)*spacing)):zoom(judgeFontSize):halign(1) - self:settext(0) - end; + self:xy(0,5+((k-1)*spacing)):zoomto(frameWidth,5):halign(0):valign(0) + self:diffuse(color(colorConfig:get_data().judgment[v])):diffusealpha(0) + end, SetCommand=function(self) - if k > 6 then -- HoldNoteScores - self:settext(pss:GetHoldNoteScores(v)) - else - self:settext(pss:GetTapNoteScores(v)) - end - end; + self:stoptweening() + self:linear(0.1) + self:diffusealpha(highlightOpacity) + self:linear(0.5) + self:diffusealpha(0) + end } - end - return t -end; - -if enabled1P then - t[#t+1] = judgeCounter(PLAYER_1) -end + t[#t+1] = LoadFont("Common normal")..{ + InitCommand = function(self) + self:xy(5,7+((k-1)*spacing)):zoom(judgeFontSize):halign(0) + if not bareBone then + self:settext(getJudgeStrings(v)) + self:diffuse(color(colorConfig:get_data().judgment[v])) + else + self:settext(getShortJudgeStrings(v)) + end + end + } -if enabled2P then - t[#t+1] = judgeCounter(PLAYER_2) -end + t[#t+1] = LoadFont("Common Normal") .. { + Name=PLAYER_1..v.."Count", + InitCommand = function(self) + self:xy(frameWidth-5,7+((k-1)*spacing)):zoom(judgeFontSize):halign(1) + self:settext(0) + end, + SetCommand=function(self) + if k > 6 then -- HoldNoteScores + self:settext(pss:GetHoldNoteScores(v)) + else + self:settext(pss:GetTapNoteScores(v)) + end + end + } +end return t \ No newline at end of file diff --git a/BGAnimations/ScreenGameplay overlay/lanecover.lua b/BGAnimations/ScreenGameplay overlay/lanecover.lua index 820b5647..57144cfa 100644 --- a/BGAnimations/ScreenGameplay overlay/lanecover.lua +++ b/BGAnimations/ScreenGameplay overlay/lanecover.lua @@ -1,17 +1,17 @@ local moveUpP1 = false local moveDownP1 = false -local moveUpP2 = false -local moveDownP2 = false - local lockSpeedP1 = false -local lockSpeedP2 = false + +local cover local laneColor = color(colorConfig:get_data().gameplay.LaneCover) local cols = GAMESTATE:GetCurrentStyle():ColumnsPerPlayer() +local allowedCustomization = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay - -local width = GHETTOGAMESTATE:getNoteFieldWidth(PLAYER_1) +local isCentered = ((cols >= 6) or PREFSMAN:GetPreference("Center1Player")) and GAMESTATE:GetNumPlayersEnabled() == 1 +-- load from prefs later +local width = 64 * cols * MovableValues.NotefieldWidth local padding = 8 local styleType = ToEnumShortString(GAMESTATE:GetCurrentStyle():GetStyleType()) @@ -20,84 +20,116 @@ local enabledP1 = prefsP1 ~= 0 and GAMESTATE:IsPlayerEnabled(PLAYER_1) local isReverseP1 = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingReverse() if prefsP1 == 2 then -- it's a Hidden LaneCover isReverseP1 = not isReverseP1 -end; - -local prefsP2 = playerConfig:get_data(pn_to_profile_slot(PLAYER_2)).LaneCover -local enabledP2 = prefsP2 ~= 0 and GAMESTATE:IsPlayerEnabled(PLAYER_2) -local isReverseP2 = GAMESTATE:GetPlayerState(PLAYER_2):GetCurrentPlayerOptions():UsingReverse() -if prefsP2 == 2 then -- it's a Hidden LaneCover - isReverseP2 = not isReverseP2 -end; - +end local heightP1 = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).LaneCoverHeight -local heightP2 = playerConfig:get_data(pn_to_profile_slot(PLAYER_2)).LaneCoverHeight - -local P1X = GHETTOGAMESTATE.getNoteFieldPos(PLAYER_1) -local P2X = GHETTOGAMESTATE.getNoteFieldPos(PLAYER_2) +local P1X = + SCREEN_CENTER_X + MovableValues.NotefieldX +if not isCentered then + P1X = THEME:GetMetric("ScreenGameplay", string.format("PlayerP1%sX", styleType)) +end local function getPlayerBPM(pn) + local pn = GAMESTATE:GetMasterPlayerNumber() local songPosition = GAMESTATE:GetPlayerState(pn):GetSongPosition() local ts = SCREENMAN:GetTopScreen() local bpm = 0 - if ts:GetScreenType() == 'ScreenType_Gameplay' then + if ts:GetScreenType() == "ScreenType_Gameplay" then bpm = ts:GetTrueBPS(pn) * 60 - end; + end return bpm -end; +end local function getMaxDisplayBPM(pn) + local pn = GAMESTATE:GetMasterPlayerNumber() local song = GAMESTATE:GetCurrentSong() local steps = GAMESTATE:GetCurrentSteps(pn) - if steps:GetDisplayBPMType() ~= 'DisplayBPM_Random' then + if steps:GetDisplayBPMType() ~= "DisplayBPM_Random" then return steps:GetDisplayBpms()[2] else return steps:GetTimingData():GetActualBPM()[2] - end; -end; + end +end local function getSpeed(pn) - local po = GAMESTATE:GetPlayerState(pn):GetPlayerOptions("ModsLevel_Preferred"); + local po = GAMESTATE:GetPlayerState(pn):GetPlayerOptions("ModsLevel_Preferred") if po:XMod() ~= nil then - return po:XMod()*getPlayerBPM(pn) + return po:XMod() * getPlayerBPM(pn) elseif po:CMod() ~= nil then return po:CMod() elseif po:MMod() ~= nil then - return po:MMod()*(getPlayerBPM(pn)/getMaxDisplayBPM(pn)) + return po:MMod() * (getPlayerBPM(pn) / getMaxDisplayBPM(pn)) else return getPlayerBPM(pn) - end; -end; + end +end + +local yoffsetreverse = THEME:GetMetric("Player", "ReceptorArrowsYReverse") +local yoffsetstandard = THEME:GetMetric("Player", "ReceptorArrowsYStandard") local function getNoteFieldHeight(pn) - local reverse = GAMESTATE:GetPlayerState(pn):GetCurrentPlayerOptions():UsingReverse() - if reverse then - return SCREEN_CENTER_Y + THEME:GetMetric("Player","ReceptorArrowsYReverse") + local usingreverse = GAMESTATE:GetPlayerState(pn):GetCurrentPlayerOptions():UsingReverse() + if usingreverse then + return SCREEN_CENTER_Y + yoffsetreverse else - return SCREEN_CENTER_Y - THEME:GetMetric("Player","ReceptorArrowsYStandard") - end; -end; + return SCREEN_CENTER_Y - yoffsetstandard + end +end -local function getScrollSpeed(pn,LaneCoverHeight) +local function getScrollSpeed(pn, LaneCoverHeight) local height = getNoteFieldHeight(pn) local speed = getSpeed(pn) if LaneCoverHeight < height then - return speed*(height/(height-LaneCoverHeight)) + return speed * (height / (height - LaneCoverHeight)) else return 0 - end; -end; + end +end + +--inaccurate since the highspeed x1 speed definition is different between the games. +--iidx x1 is defined as the whole measure showing up on the notefield +--SM x1 is defined as 4th notes being next to each other with no gaps or overlaps. +--Also note that the number given by this function does not take into account the fact +-- the notefield may have been moved up or down. It also does not work for the Hidden mode. +local function getIIDXGreenNumber(pn, LaneCoverHeight) + return (174 * ((getNoteFieldHeight(pn) - LaneCoverHeight) * (1000 / getNoteFieldHeight(pn)))) / + ((getSpeed(pn) / getPlayerBPM(pn)) * getPlayerBPM(pn)) +end + +local function input(event) + if getAutoplay() ~= 0 and playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).LaneCover ~= 0 then + if Movable.current == "DeviceButton_r" and event.type ~= "InputEventType_Release" then + if event.DeviceInput.button == "DeviceButton_left" then + cover:addx(-3) + end + if event.DeviceInput.button == "DeviceButton_right" then + cover:addx(3) + end + end + if Movable.current == "DeviceButton_t" and event.type ~= "InputEventType_Release" then + if event.DeviceInput.button == "DeviceButton_left" then + width = 64 * cols * MovableValues.NotefieldWidth - 0.01 + cover:playcommand("Update") + end + if event.DeviceInput.button == "DeviceButton_right" then + width = 64 * cols * MovableValues.NotefieldWidth + 0.01 + cover:playcommand("Update") + end + end + end + return false +end -local t = Def.ActorFrame{ +local t = + Def.ActorFrame { CodeMessageCommand = function(self, params) moveDownP1 = false moveUpP1 = false - moveDownP2 = false - moveUpP2 = false - if params.PlayerNumber == PLAYER_1 then + local doot = heightP1 + if params.PlayerNumber == PLAYER_1 and allowedCustomization then if params.Name == "LaneUp" then moveUpP1 = true elseif params.Name == "LaneDown" then @@ -106,188 +138,144 @@ local t = Def.ActorFrame{ moveDownP1 = false moveUpP1 = false end - end; - if params.PlayerNumber == PLAYER_2 then - if params.Name == "LaneUp" then - moveUpP2 = true - elseif params.Name == "LaneDown" then - moveDownP2 = true - else - moveDownP2 = false - moveUpP2 = false - end - end; - self:playcommand("SavePrefs") - end; - SavePrefsCommand=function(self) + self:playcommand("SavePrefs") + end + end, + SavePrefsCommand = function(self) if enabledP1 then playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).LaneCoverHeight = heightP1 playerConfig:set_dirty(pn_to_profile_slot(PLAYER_1)) playerConfig:save(pn_to_profile_slot(PLAYER_1)) - end; - if enabledP2 then - playerConfig:get_data(pn_to_profile_slot(PLAYER_2)).LaneCoverHeight = heightP2 - playerConfig:set_dirty(pn_to_profile_slot(PLAYER_2)) - playerConfig:save(pn_to_profile_slot(PLAYER_2)) - end; - end; + end + end, + OnCommand = function() + if (allowedCustomization) then + SCREENMAN:GetTopScreen():AddInputCallback(input) + end + end } if enabledP1 then - t[#t+1] = Def.Quad{ - Name="CoverP1"; - InitCommand=function(self) - self:xy(P1X,SCREEN_TOP):zoomto((width+padding)*GHETTOGAMESTATE:getNoteFieldScale(PLAYER_1),heightP1):valign(0):diffuse(laneColor) - end; - BeginCommand=function(self) + t[#t + 1] = + Def.Quad { + Name = "CoverP1", + InitCommand = function(self) + self:xy(P1X, SCREEN_TOP):zoomto((width + padding) * getNoteFieldScale(PLAYER_1), heightP1):valign(0):diffuse( + laneColor + ) + cover = self + end, + BeginCommand = function(self) if isReverseP1 then self:y(SCREEN_TOP) self:valign(0) else self:y(SCREEN_BOTTOM) self:valign(1) - end; - end; - }; - - t[#t+1] = LoadFont("Common Normal")..{ - Name="CoverTextP1White"; - InitCommand=function(self) - self:x(P1X-(width*GHETTOGAMESTATE:getNoteFieldScale(PLAYER_1)/8)):settext(0):valign(1):zoom(0.5) - end; - BeginCommand=function(self) - self:settext(0) - if isReverseP1 then - self:y(heightP1-5) - self:valign(1) - else - self:y(SCREEN_BOTTOM-heightP1+5) - self:valign(0) - end; - self:finishtweening() - self:diffusealpha(1) - self:sleep(0.25) - self:smooth(0.75) - self:diffusealpha(0) - end; - }; - t[#t+1] = LoadFont("Common Normal")..{ - Name="CoverTextP1Green"; - InitCommand=function(self) - self:x(P1X+(width*GHETTOGAMESTATE:getNoteFieldScale(PLAYER_1)/8)):settext(0):valign(1):zoom(0.5):diffuse(color("#4CBB17")) - end; - BeginCommand=function(self) - self:settext(math.floor(getSpeed(PLAYER_1))) + end + end, + UpdateCommand = function(self) + P1X = SCREEN_CENTER_X + MovableValues.NotefieldX if isReverseP1 then - self:y(heightP1-5) - self:valign(1) - else - self:y(SCREEN_BOTTOM-heightP1+5) - self:valign(0) - end; - self:finishtweening() - self:diffusealpha(1) - self:sleep(0.25) - self:smooth(0.75) - self:diffusealpha(0) - end; - }; -end; - -if enabledP2 then - t[#t+1] = Def.Quad{ - Name="CoverP2"; - InitCommand=function(self) - self:xy(P2X,SCREEN_TOP):zoomto((width+padding)*GHETTOGAMESTATE:getNoteFieldScale(PLAYER_2),heightP2):valign(0):diffuse(laneColor) - end; - BeginCommand=function(self) - if isReverseP2 then + self:xy(P1X, SCREEN_TOP):zoomto((width + padding) * getNoteFieldScale(PLAYER_1), heightP1):valign(0):diffuse( + laneColor + ) self:y(SCREEN_TOP) self:valign(0) else + self:xy(P1X, SCREEN_TOP):zoomto((width + padding) * getNoteFieldScale(PLAYER_1), heightP1):valign(0):diffuse( + laneColor + ) self:y(SCREEN_BOTTOM) self:valign(1) - end; - end; - }; - - t[#t+1] = LoadFont("Common Normal")..{ - Name="CoverTextP2White"; - InitCommand=function(self) - self:x(P2X-(width*GHETTOGAMESTATE:getNoteFieldScale(PLAYER_2)/8)):settext(0):valign(1):zoom(0.5) - end; - BeginCommand=function(self) - self:settext(0) - if isReverseP2 then - self:y(heightP2-5) - self:valign(1) - else - self:y(SCREEN_BOTTOM-heightP2+5) - self:valign(0) - end; - self:finishtweening() - self:diffusealpha(1) - self:sleep(0.25) - self:smooth(0.75) - self:diffusealpha(0) - end; - }; - - t[#t+1] = LoadFont("Common Normal")..{ - Name="CoverTextP2Green"; - InitCommand=function(self) - self:x(P2X+(width*GHETTOGAMESTATE:getNoteFieldScale(PLAYER_2)/8)):settext(0):valign(1):zoom(0.5):diffuse(color("#4CBB17")) - end; - BeginCommand=function(self) - self:settext(math.floor(getSpeed(PLAYER_1))) - if isReverseP2 then - self:y(heightP2-5) - self:valign(1) - else - self:y(SCREEN_BOTTOM-heightP2+5) - self:valign(0) - end; - self:finishtweening() - self:diffusealpha(1) - self:sleep(0.25) - self:smooth(0.75) - self:diffusealpha(0) - end; - }; -end; + end + cover = self + end + } + + t[#t + 1] = + LoadFont("Common Normal") .. + { + Name = "CoverTextP1White", + InitCommand = function(self) + self:x(P1X - (width * getNoteFieldScale(PLAYER_1) / 8)):settext(0):valign(1):zoom(0.5) + end, + BeginCommand = function(self) + self:settext(0) + if isReverseP1 then + self:y(heightP1 - 5) + self:valign(1) + else + self:y(SCREEN_BOTTOM - heightP1 + 5) + self:valign(0) + end + self:finishtweening() + self:diffusealpha(1) + self:sleep(0.25) + self:smooth(0.75) + self:diffusealpha(0) + end + } + t[#t + 1] = + LoadFont("Common Normal") .. + { + Name = "CoverTextP1Green", + InitCommand = function(self) + self:x(P1X + (width * getNoteFieldScale(PLAYER_1) / 8)):settext(0):valign(1):zoom(0.5):diffuse(color("#4CBB17")) + end, + BeginCommand = function(self) + self:settext(math.floor(getSpeed(PLAYER_1))) + if isReverseP1 then + self:y(heightP1 - 5) + self:valign(1) + else + self:y(SCREEN_BOTTOM - heightP1 + 5) + self:valign(0) + end + self:finishtweening() + self:diffusealpha(1) + self:sleep(0.25) + self:smooth(0.75) + self:diffusealpha(0) + end + } +end local function Update(self) - t.InitCommand=function(self) + t.InitCommand = function(self) self:SetUpdateFunction(Update) - end; + end + self:SetUpdateRate(5) if enabledP1 then + P1X = SCREEN_CENTER_X + MovableValues.NotefieldX + if moveDownP1 then if isReverseP1 then - heightP1 = math.min(SCREEN_BOTTOM,math.max(0,heightP1+1)) + heightP1 = math.min(SCREEN_BOTTOM, math.max(0, heightP1 + 0.1)) else - heightP1 = math.min(SCREEN_BOTTOM,math.max(0,heightP1-1)) - end; - end; + heightP1 = math.min(SCREEN_BOTTOM, math.max(0, heightP1 - 0.1)) + end + end if moveUpP1 then if isReverseP1 then - heightP1 = math.min(SCREEN_BOTTOM,math.max(0,heightP1-1)) + heightP1 = math.min(SCREEN_BOTTOM, math.max(0, heightP1 - 0.1)) else - heightP1 = math.min(SCREEN_BOTTOM,math.max(0,heightP1+1)) - end; - end; + heightP1 = math.min(SCREEN_BOTTOM, math.max(0, heightP1 + 0.1)) + end + end self:GetChild("CoverP1"):zoomy(heightP1) - self:GetChild("CoverTextP1White"):settext(heightP1) + self:GetChild("CoverTextP1White"):settext(math.floor(heightP1)) if prefsP1 == 1 then -- don't update greennumber for hidden lanecovers - self:GetChild("CoverTextP1Green"):settext(math.floor(getScrollSpeed(PLAYER_1,heightP1))) - end; + self:GetChild("CoverTextP1Green"):settext(math.floor(getScrollSpeed(PLAYER_1, heightP1))) + end if isReverseP1 then - self:GetChild("CoverTextP1White"):y(heightP1-5) - self:GetChild("CoverTextP1Green"):y(heightP1-5) + self:GetChild("CoverTextP1White"):y(heightP1 - 5) + self:GetChild("CoverTextP1Green"):y(heightP1 - 5) else - self:GetChild("CoverTextP1White"):y(SCREEN_BOTTOM-heightP1+5) - self:GetChild("CoverTextP1Green"):y(SCREEN_BOTTOM-heightP1+5) - end; + self:GetChild("CoverTextP1White"):y(SCREEN_BOTTOM - heightP1 + 5) + self:GetChild("CoverTextP1Green"):y(SCREEN_BOTTOM - heightP1 + 5) + end if moveDownP1 or moveUpP1 then self:GetChild("CoverTextP1White"):finishtweening() @@ -300,56 +288,15 @@ local function Update(self) self:GetChild("CoverTextP1Green"):sleep(0.25) self:GetChild("CoverTextP1Green"):smooth(0.75) self:GetChild("CoverTextP1Green"):diffusealpha(0) - end; - - end; - - if enabledP2 then - if moveDownP2 then - if isReverseP2 then - heightP2 = math.min(SCREEN_BOTTOM,math.max(0,heightP2+1)) - else - heightP2 = math.min(SCREEN_BOTTOM,math.max(0,heightP2-1)) - end; - end; - if moveUpP2 then - if isReverseP2 then - heightP2 = math.min(SCREEN_BOTTOM,math.max(0,heightP2-1)) - else - heightP2 = math.min(SCREEN_BOTTOM,math.max(0,heightP2+1)) - end; - end; - self:GetChild("CoverP2"):zoomy(heightP2) - self:GetChild("CoverTextP2White"):settext(heightP2) - if prefsP2 == 1 then - self:GetChild("CoverTextP2Green"):settext(math.floor(getScrollSpeed(PLAYER_2,heightP2))) - end; - if isReverseP2 then - self:GetChild("CoverTextP2White"):y(heightP2-5) - self:GetChild("CoverTextP2Green"):y(heightP2-5) - else - self:GetChild("CoverTextP2White"):y(SCREEN_BOTTOM-heightP2+5) - self:GetChild("CoverTextP2Green"):y(SCREEN_BOTTOM-heightP2+5) - end; - - if moveDownP2 or moveUpP2 then - self:GetChild("CoverTextP2White"):finishtweening() - self:GetChild("CoverTextP2White"):diffusealpha(1) - self:GetChild("CoverTextP2White"):sleep(0.25) - self:GetChild("CoverTextP2White"):smooth(0.75) - self:GetChild("CoverTextP2White"):diffusealpha(0) - - self:GetChild("CoverTextP2Green"):finishtweening() - self:GetChild("CoverTextP2Green"):diffusealpha(1) - self:GetChild("CoverTextP2Green"):sleep(0.25) - self:GetChild("CoverTextP2Green"):smooth(0.75) - self:GetChild("CoverTextP2Green"):diffusealpha(0) - end; - end; -end; -t.InitCommand=function(self) - self:SetUpdateFunction(Update) -end; - + self:GetChild("CoverTextP1White"):x(P1X - (width * getNoteFieldScale(PLAYER_1) / 8)) + self:GetChild("CoverTextP1Green"):x(P1X + (width * getNoteFieldScale(PLAYER_1) / 8)) + end + end +end +if allowedCustomization then + t.InitCommand = function(self) + self:SetUpdateFunction(Update) + end +end -return t \ No newline at end of file +return t diff --git a/BGAnimations/ScreenGameplay overlay/leaderboard.lua b/BGAnimations/ScreenGameplay overlay/leaderboard.lua new file mode 100644 index 00000000..5704c8eb --- /dev/null +++ b/BGAnimations/ScreenGameplay overlay/leaderboard.lua @@ -0,0 +1,414 @@ +local allowedCustomization = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay +local leaderboardEnabled = + (NSMAN:IsETTP() and SCREENMAN:GetTopScreen() and SCREENMAN:GetTopScreen():GetName() == "ScreenNetStageInformation") or + (playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).leaderboardEnabled and DLMAN:IsLoggedIn()) +local animated = themeConfig:get_data().global.AnimatedLeaderboard +local entryActors = {} +local indexDifferences = {} +local beforeSort = {} +local sortedIndices = {} + +-- Overall ActorFrame (container) +local t = + Widg.Container { + x = MovableValues.LeaderboardX, + y = MovableValues.LeaderboardY, + name = "Leaderboard" +} + +-- Don't load the leaderboard stuff if we don't want it +if not leaderboardEnabled then + return t +end + +-- "Modifiable" content +local CRITERIA = "GetWifeScore" +local NUM_ENTRIES = themeConfig:get_data().global.LeaderboardSlots +local ENTRY_HEIGHT = IsUsingWideScreen() and 35 or 20 +local WIDTH = SCREEN_WIDTH * (IsUsingWideScreen() and 0.275 or 0.25) +local jdgs = { + -- Table of judgments for the judgecounter + "TapNoteScore_W1", + "TapNoteScore_W2", + "TapNoteScore_W3", + "TapNoteScore_W4", + "TapNoteScore_W5", + "TapNoteScore_Miss" +} + +-- Function handed to CustomizeGameplay for element spacing +local function arbitraryLeaderboardSpacing(value) + for i, entry in ipairs(entryActors) do + entry.container:addy((i - 1) * value) + end + if allowedCustomization then + Movable.DeviceButton_s.Border:playcommand( + "ChangeHeight", + {val = entryActors[#entryActors].container:GetY() + ENTRY_HEIGHT} + ) + end +end + +-- ???? +if not DLMAN:GetCurrentRateFilter() then + DLMAN:ToggleRateFilter() +end + +---- Multiplayer section of code ---- +local multiScores = {} + +-- Function used to redirect scoreboard table elements to multiplayer scoreboard data +local function scoreUsingMultiScore(idx) + return { + GetDisplayName = function() + return multiScores[idx] and multiScores[idx].user or nil + end, + GetWifeGrade = function() + return multiScores[idx] and GetGradeFromPercent(multiScores[idx].wife) or "Grade_Tier01" + end, + GetWifeScore = function() + return multiScores[idx] and multiScores[idx].wife or -5000000 + end, + GetSkillsetSSR = function() + return -1 + end, + GetJudgmentString = function() + return multiScores[idx] and multiScores[idx].jdgstr or "" + end + } +end + +local onlineScores = {} +local isMulti = NSMAN:IsETTP() and SCREENMAN:GetTopScreen() and SCREENMAN:GetTopScreen():GetName() == "ScreenNetStageInformation" or false + +-- If we are in multiplayer, use that redirect above +-- Otherwise, we will use the scores from the chart leaderboards +if isMulti then + multiScores = NSMAN:GetMPLeaderboard() + for i = 1, NUM_ENTRIES do + onlineScores[i] = scoreUsingMultiScore(i) + end +else + onlineScores = DLMAN:GetChartLeaderBoard(GAMESTATE:GetCurrentSteps(PLAYER_1):GetChartKey()) +end + +-- how to use table.sort() +local sortFunction = function(h1, h2) + return h1[CRITERIA](h1) > h2[CRITERIA](h2) +end +table.sort(onlineScores, sortFunction) -- a little sort never hurt anybody + +-- A table which mocks the format of a HighScore but holds other info instead +-- Used for the player's current score +local curScore +curScore = { + GetDisplayName = function() + return DLMAN:GetUsername() + end, + GetWifeGrade = function() + return GetGradeFromPercent(curScore.curWifeScore) + end, + GetWifeScore = function() + return curScore.curWifeScore + end, + GetSkillsetSSR = function() + return -1 + end, + GetJudgmentString = function() + local str = "" + for i, v in ipairs(jdgs) do + str = str .. curScore.jdgVals[v] .. " | " + end + return str .. "x" .. curScore.combo + end +} +curScore.combo = 0 +curScore.curWifeScore = 0 +curScore.curGrade = "Grade_Tier02" +curScore.jdgVals = { + ["TapNoteScore_W1"] = 0, + ["TapNoteScore_W2"] = 0, + ["TapNoteScore_W3"] = 0, + ["TapNoteScore_W4"] = 0, + ["TapNoteScore_W5"] = 0, + ["TapNoteScore_Miss"] = 0 +} + +-- The table for the data being displayed +local scoreboard = {} + +-- Emplace chart leaderboard/multi data into all but one of the scoreboard elements +for i = 1, NUM_ENTRIES - 1 do + scoreboard[i] = onlineScores[i] +end +local done = false +if not isMulti then -- if not in multi, use the last slot for the player's score + for i = 1, NUM_ENTRIES do + if not done and not scoreboard[i] then + scoreboard[i] = curScore + done = true + end + end +end +table.sort(scoreboard, sortFunction) -- sort it again why not + +-- Prepare the list of entries (the containers of the leaderboard elements) that we will use to call update functions for later +for i = 1, NUM_ENTRIES do + entryActors[i] = {} +end + +-- creates a single box in the leaderboard container, with all its info +function scoreEntry(i) + local entryActor + + -- locally hold an "entry" which is a Widg.Container. + -- Widg.Containers take a customized set of parameters through a table, like our usual Def.ActorFrames + -- making "entry" sets some defaults for it + local entry = + Widg.Container { + x = 0, + y = (i - 1) * ENTRY_HEIGHT * 1.3, + onInit = function(self) + entryActor = self + entryActors[i]["container"] = self + self.update = function(self, hs) + self:visible(not (not hs)) + local diff = indexDifferences[i] + if not(not hs) and diff ~= nil and diff ~= 0 then + self:finishtweening() + if animated then + self:linear(0.2) + end + self:addy(diff * ENTRY_HEIGHT * 1.3) + end + end + self:update(scoreboard[i]) + end + } + -- Put the background box in the entry container + entry:add( + Widg.Rectangle { + width = WIDTH, + height = ENTRY_HEIGHT, + color = getLeaderboardColor("background"), + halign = 0.5 + } + ) + + -- Make another container to hold the text labels + local labelContainer = + Widg.Container { + x = WIDTH / 5 + } + entry:add(labelContainer) + local y + -- Make a function with preset parameters to add text to that text label container + local addLabel = function(name, fn, x, y) + y = (y or 0) - (IsUsingWideScreen() and 0 or ENTRY_HEIGHT / 3.2) + labelContainer:add( + Widg.Label { + onInit = function(self) + entryActors[i][name] = self + self.update = function(self, hs) + if hs then + self:visible(true) + fn(self, hs) + else + self:visible(false) + end + end + self:update(scoreboard[i]) + end, + halign = 0, + scale = 0.4, + x = (x - WIDTH / 2) * 0.4, + y = 10 + y, + text = "", + color = getLeaderboardColor("text") + } + ) + end + + -- Proceed adding those labels with their appropriate update methods + addLabel( + "rank", + function(self, hs) + self:settext(tostring(sortedIndices[i])) + end, + 5, + ENTRY_HEIGHT / 4 + ) + addLabel( + "ssr", + function(self, hs) + local ssr = hs:GetSkillsetSSR("Overall") + if ssr < 0 then + self:settext("") + else + self:settextf("%.2f", ssr):diffuse(byMSD(ssr)) + end + end, + WIDTH / 5 + ) + addLabel( + "name", + function(self, hs) + local n = hs:GetDisplayName() + self:settext(n or "") + if entryActor then + entryActor:visible(not (not n)) + end + end, + WIDTH / 1.3 + ) + addLabel( + "wife", + function(self, hs) + self:settextf("%05.2f%%", hs:GetWifeScore() * 100):diffuse(byGrade(hs:GetWifeGrade())) + end, + 1.8 * WIDTH + ) + addLabel( + "grade", + function(self, hs) + self:settext(getGradeStrings(hs:GetWifeGrade())) + self:diffuse(byGrade(hs:GetWifeGrade())) + self:halign(0.5) + end, + 2 * WIDTH, + ENTRY_HEIGHT / 2 + ) + addLabel( + "judges", + function(self, hs) + self:settext(hs:GetJudgmentString()) + end, + WIDTH / 5, + ENTRY_HEIGHT / 2 + ) + + return entry +end + +-- Now make x entries +for i = 1, NUM_ENTRIES do + t[#t + 1] = scoreEntry(i) +end + +-- ... oh no +local function deepcopy(orig) + local orig_type = type(orig) + local copy + if orig_type == 'table' then + copy = {} + for orig_key, orig_value in next, orig, nil do + copy[deepcopy(orig_key)] = deepcopy(orig_value) + end + setmetatable(copy, deepcopy(getmetatable(orig))) + else + copy = orig + end + return copy +end +beforeSort = deepcopy(scoreboard) +for i = 1, NUM_ENTRIES do + sortedIndices[i] = i +end +--- + +-- Adding commands to the output ActorFrame +-- Similar to placing these directly within the ActorFrame definition +t.ComboChangedMessageCommand = function(self, params) + curScore.combo = params.PlayerStageStats and params.PlayerStageStats:GetCurrentCombo() or params.OldCombo +end +t.JudgmentMessageCommand = function(self, params) + if curScore.jdgVals[params.Judgment] then + curScore.jdgVals[params.Judgment] = params.Val + end + -- params.curWifeScore retrieves the Judgment Message curWifeScore which is a raw number for calculations; very large + -- the online highscore curWifeScore is the wife percent... + -- params.WifePercent is our current calculated wife percent. + local old = curScore.curWifeScore + curScore.curWifeScore = notShit.floor(params.WifePercent * 100) / 10000 + if isMulti then + multiScores = NSMAN:GetMPLeaderboard() + end + if old ~= curScore.curWifeScore then + + -- What follows is an unfortunate block of sorting and looping + -- Thankfully we aren't dealing with thousands of elements or I might be blacklisted from programming globally + local anothercopy = deepcopy(beforeSort) + table.sort(anothercopy, sortFunction) + for i = 1, NUM_ENTRIES do + local index = i + local foundIndex = 1 + local convertIndex = 1 + local foundCases = {} + for j, score in ipairs(anothercopy) do -- to determine the difference in indices after sorting + if beforeSort[i] ~= nil and beforeSort[i]:GetDisplayName() == score:GetDisplayName() and beforeSort[i]:GetWifeScore() == score:GetWifeScore() then + foundIndex = j + foundCases[1] = true + break + end + end + for j, score in ipairs(scoreboard) do -- to find what the original scoreboard index is from a sorted score + if beforeSort[i] ~= nil and beforeSort[i]:GetDisplayName() == score:GetDisplayName() and beforeSort[i]:GetWifeScore() == score:GetWifeScore() then + convertIndex = j + foundCases[2] = true + break + end + end + for j, score in ipairs(scoreboard) do -- to find out the position of this score after sorting + if anothercopy[i] ~= nil and anothercopy[i]:GetDisplayName() == score:GetDisplayName() and anothercopy[i]:GetWifeScore() == score:GetWifeScore() then + sortedIndices[j] = i + foundCases[3] = true + break + end + end + if foundCases[1] and foundCases[2] and foundCases[3] then + indexDifferences[convertIndex] = foundIndex - index + else + indexDifferences[convertIndex] = 0 + end + end + beforeSort = deepcopy(anothercopy) + --- Now that that's over with.... + + -- Tell all the text labels to update. + for i, entry in ipairs(entryActors) do + for name, label in pairs(entry) do + label:update(scoreboard[i]) + end + end + end +end + +-- Border for CustomizeGameplay +t[#t + 1] = MovableBorder(WIDTH, 200, 1, 0, 0) + +t.OnCommand = function(self, params) + if allowedCustomization then + Movable.DeviceButton_a.element = self + Movable.DeviceButton_s.element = self + Movable.DeviceButton_a.condition = true + Movable.DeviceButton_s.condition = true + Movable.DeviceButton_d.condition = NUM_ENTRIES > 1 + Movable.DeviceButton_d.DeviceButton_up.arbitraryFunction = arbitraryLeaderboardSpacing + Movable.DeviceButton_d.DeviceButton_down.arbitraryFunction = arbitraryLeaderboardSpacing + Movable.DeviceButton_s.Border = self:GetChild("Border") + Movable.DeviceButton_d.Border = self:GetChild("Border") + setBorderAlignment(self:GetChild("Border"), 0, 0) + end + arbitraryLeaderboardSpacing(MovableValues.LeaderboardSpacing) + self:zoomtowidth(MovableValues.LeaderboardWidth) + self:zoomtoheight(MovableValues.LeaderboardHeight) + for i, entry in ipairs(entryActors) do + for name, label in pairs(entry) do + if scoreboard[i] ~= nil then + label:visible(not (not scoreboard[i]:GetDisplayName())) + end + end + end +end + +return t diff --git a/BGAnimations/ScreenGameplay overlay/messagebox.lua b/BGAnimations/ScreenGameplay overlay/messagebox.lua new file mode 100644 index 00000000..8e221294 --- /dev/null +++ b/BGAnimations/ScreenGameplay overlay/messagebox.lua @@ -0,0 +1,76 @@ +local settext = BitmapText.settext +local isPractice = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingPractice() + +local function highlight(self) + self:queuecommand("Highlight") +end + +local function highlightIfOver(self) + if isOver(self) then + self:diffusealpha(0.2) + else + self:diffusealpha(1) + end +end + +return Def.ActorFrame { + OnCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(MovableInput) + self:SetUpdateFunction(highlight) + end, + Def.BitmapText { + Name = "message", + Font = "Common Normal", + InitCommand = function(self) + Movable.message = self + self:horizalign(left):vertalign(top):shadowlength(2):xy(10, 20):zoom(.5):visible(false) + end + }, + Def.BitmapText { + Name = "Instructions", + Font = "Common Normal", + InitCommand = function(self) + self:horizalign(left):vertalign(top):xy(SCREEN_WIDTH - 240, 20):zoom(.45):visible(true) + end, + HighlightCommand = function(self) + highlightIfOver(self) + end, + OnCommand = function(self) + local text = { + "Enable AutoplayCPU with shift+f8\n", + "Press keys to toggle active elements", + "Right click cancels any active element\n", + "1: Judgement Text Position", + "2: Judgement Text Size", + "3: Combo Text Position", + "4: Combo Text Size", + "5: Error Bar Position", + "6: Error Bar Size", + "7: Target Tracker Position", + "8: Target Tracker Size", + "w: Display Percent Text Position", + "e: Display Percent Text Size", + "r: Notefield Position", + "t: Notefield Size", + "y: NPS Display Text Position", + "u: NPS Display Text Size", + "i: NPS Graph Position", + "o: NPS Graph Size", + "p: Judge Counter Position", + "a: Leaderboard Position", + "s: Leaderboard Size", + "d: Leaderboard Spacing", + --"h: Replay Buttons Spacing", + "j: Player Info Position", + "k: Player Info Size", + } + if playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).LaneCover ~= 0 then + table.insert(text, "/: Lane Cover Height") + end + if isPractice then + table.insert(text, "z: Density Graph Position") + end + self:settext(table.concat(text, "\n")) + end + } +} diff --git a/BGAnimations/ScreenGameplay overlay/npscalc.lua b/BGAnimations/ScreenGameplay overlay/npscalc.lua index df22f0a2..e9872742 100644 --- a/BGAnimations/ScreenGameplay overlay/npscalc.lua +++ b/BGAnimations/ScreenGameplay overlay/npscalc.lua @@ -1,332 +1,315 @@ -- A moving average NPS calculator -local debug = false +-- movable stuff +local allowedCustomization = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay +--still kept this here because idk man +local enabled = { + NPSDisplay = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).NPSDisplay, + NPSGraph = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).NPSGraph +} + +local countNotesSeparately = GAMESTATE:CountNotesSeparately() -- Generally, a smaller window will adapt faster, but a larger window will have a more stable value. -local maxWindow = 3 --themeConfig:get_data().NPSDisplay.MaxWindow -- this will be the maximum size of the "window" in seconds. -local minWindow = 3 --themeConfig:get_data().NPSDisplay.MinWindow -- this will be the minimum size of the "window" in seconds. Unused for now. +local maxWindow = themeConfig:get_data().NPSDisplay.MaxWindow / 2 -- this will be the maximum size of the "window" in seconds. +local minWindow = themeConfig:get_data().NPSDisplay.MinWindow / 2 -- this will be the minimum size of the "window" in seconds. + +isCentered = PREFSMAN:GetPreference("Center1Player") +local CenterX = SCREEN_CENTER_X +local mpOffset = 0 +if not isCentered then + CenterX = + THEME:GetMetric( + "ScreenGameplay", + string.format("PlayerP1%sX", ToEnumShortString(GAMESTATE:GetCurrentStyle():GetStyleType())) + ) + mpOffset = SCREEN_CENTER_X + 60 +end --Graph related stuff -local graphLastUpdate = 0 -local maxVerts = 300 -local graphUpdateRate = 0.1 local initialPeak = 10 -- Initial height of the NPS graph. local graphWidth = capWideScale(50,90) local graphHeight = 50 -local graphPos = { -- Position of the NPS graph - PlayerNumber_P1 = { - X = 0, - Y = 100 - }, - PlayerNumber_P2 = { - X = SCREEN_WIDTH-graphWidth, - Y = 100 - } -} +local maxVerts = 150 -- Higher numbers allows for more detailed graph that spans for a longer duration. But may lead to performance issues +local graphFreq = 0.2 -- The frequency in which the graph updates in seconds. +local lifeGraph = false -- SHow lifegraph +-------------------- -local textPos = { -- Position of the NPS text - PlayerNumber_P1 = { - X = 5, - Y = 84 - }, - PlayerNumber_P2 = { - X = SCREEN_WIDTH-graphWidth, - Y = 84 - } -} - -local enabled = { - NPSDisplay = { - PlayerNumber_P1 = GAMESTATE:IsPlayerEnabled(PLAYER_1) and playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).NPSDisplay, - PlayerNumber_P2 = GAMESTATE:IsPlayerEnabled(PLAYER_2) and playerConfig:get_data(pn_to_profile_slot(PLAYER_2)).NPSDisplay - }, - NPSGraph = { - PlayerNumber_P1 = GAMESTATE:IsPlayerEnabled(PLAYER_1) and playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).NPSGraph, - PlayerNumber_P2 = GAMESTATE:IsPlayerEnabled(PLAYER_2) and playerConfig:get_data(pn_to_profile_slot(PLAYER_2)).NPSGraph - } -} - -local npsWindow = { - PlayerNumber_P1 = maxWindow, - PlayerNumber_P2 = maxWindow, -} +local npsWindow = maxWindow -- This table holds the timestamp of each judgment for each player. -- being considered for the moving average and the size of the chord. -- (let's just call this notes for simplicity) -local noteTable = { - PlayerNumber_P1 = {}, - PlayerNumber_P2 = {}, -} +local noteTable = {} -local lastJudgment = { - PlayerNumber_P1 = 'TapNoteScore_None', - PlayerNumber_P2 = 'TapNoteScore_None' -} +local lastJudgment = "TapNoteScore_None" -- Total sum of notes inside the moving average window for each player. -- The values are added/subtracted whenever we add/remove a note from the noteTable. -- This allows us to get the total sum of notes that were hit without --- iterating through the entire noteTable to get the sum. -local noteSum = { - PlayerNumber_P1 = 0, - PlayerNumber_P2 = 0, -} - -local peakNPS = { - PlayerNumber_P1 = 0, - PlayerNumber_P2 = 0, -} +-- iterating through the entire noteTable to get the sum. +local noteSum = 0 +local peakNPS = 0 --------------- --- Functions -- +-- Functions -- --------------- -- This function will take the player, the timestamp, -- and the size of the chord and append it to noteTable. --- The function will also add the size of the chord to noteSum +-- The function will also add the size of the chord to noteSum -- This function is called whenever a JudgmentMessageCommand for regular tap note occurs. -- (simply put, whenever you hit/miss a note) -local function addNote(pn,time,size) - noteTable[pn][#noteTable[pn]+1] = {time,size} - noteSum[pn] = noteSum[pn]+size -end +local function addNote(pn, time, size) + if countNotesSeparately == true then + size = 1 + end + noteTable[#noteTable + 1] = {time, size} + noteSum = noteSum + size +end --- This function is called every frame to check if there are notes that +-- This function is called every frame to check if there are notes that -- are old enough to remove from the table. -- Every time it is called, the function will loop and remove all old notes -- from noteTable and subtract the corresponding chord size from noteSum. local function removeNote(pn) - while true do - if #noteTable[pn] >= 1 then - if noteTable[pn][1][1] + npsWindow[pn] < GetTimeSinceStart() then - noteSum[pn] = noteSum[pn] - noteTable[pn][1][2] - table.remove(noteTable[pn],1) + local exit = false + while not exit do + if #noteTable >= 1 then + if noteTable[1][1] + npsWindow < GetTimeSinceStart() then + noteSum = noteSum - noteTable[1][2] + table.remove(noteTable, 1) else - break + exit = true end else - break + exit = true end end end - -- The function simply Calculates the moving average NPS -- Generally this is just nps = noteSum/window. local function getCurNPS(pn) - return noteSum[pn]/clamp(GAMESTATE:GetSongPosition():GetMusicSeconds(),minWindow,npsWindow[pn]) + return noteSum / clamp(GAMESTATE:GetSongPosition():GetMusicSeconds(), minWindow, npsWindow) end - - -- This is an update function that is being called every frame while this is loaded. local function Update(self) - self.InitCommand=function(self) + self.InitCommand = function(self) self:SetUpdateFunction(Update) - end + end - for _,pn in pairs(GAMESTATE:GetEnabledPlayers()) do - if enabled.NPSDisplay[pn] or enabled.NPSGraph[pn] then - -- We want to constantly check for old notes to remove and update the NPS counter text. - removeNote(pn) + if enabled.NPSDisplay or enabled.NPSGraph then + -- We want to constantly check for old notes to remove and update the NPS counter text. + removeNote(PLAYER_1) - curNPS = getCurNPS(pn) + curNPS = getCurNPS(PLAYER_1) - -- Update peak nps. Only start updating after enough time has passed. - if GAMESTATE:GetSongPosition():GetMusicSeconds() > npsWindow[pn] then - peakNPS[pn] = math.max(peakNPS[pn],curNPS) - end - -- the actor which called this update function passes itself down as "self". - -- we then have "self" look for the child named "Text" which you can see down below. - -- Then the settext function is called (or settextf for formatted ones) to set the text of the child "Text" - -- every time this function is called. - -- We don't display the decimal values due to lack of precision from having a relatively small time window. - if enabled.NPSDisplay[pn] then - self:GetChild("npsDisplay"..pn):GetChild("Text"):settextf("%0.0f NPS (Peak %0.0f)",curNPS,peakNPS[pn]) - end - - -- Update the graph - if enabled.NPSGraph[pn] and GetTimeSinceStart() - graphLastUpdate > graphUpdateRate then - graphLastUpdate = GetTimeSinceStart() - self:GetChild("npsGraph"..pn):playcommand("GraphUpdate") - end + -- Update peak nps. Only start updating after enough time has passed. + if GAMESTATE:GetSongPosition():GetMusicSeconds() > npsWindow then + peakNPS = math.max(peakNPS, curNPS) + end + -- the actor which called this update function passes itself down as "self". + -- we then have "self" look for the child named "Text" which you can see down below. + -- Then the settext function is called (or settextf for formatted ones) to set the text of the child "Text" + -- every time this function is called. + -- We don't display the decimal values due to lack of precision from having a relatively small time window. + if enabled.NPSDisplay then + self:GetChild("NPSDisplay"):GetChild("Text"):settextf("%0.0f NPS (Peak %0.0f)", curNPS, peakNPS) end end end local function npsDisplay(pn) - local t = Def.ActorFrame{ - Name = "npsDisplay"..pn; - -- Whenever a MessageCommand is broadcasted, - -- a table contanining parameters can also be passed along. - JudgmentMessageCommand=function(self,params) - local notes = params.Notes -- this is just one of those parameters. - - local chordsize = 0 - - if params.Player == pn then - if params.TapNoteScore and - params.TapNoteScore ~= "TapNoteScore_None" and - params.TapNoteScore ~= 'TapNoteScore_HitMine' and - params.TapNoteScore ~= 'TapNoteScore_AvoidMine' and - params.TapNoteScore ~= "TapNoteScore_CheckpointMiss" then - - - - -- The notes parameter contains a table where the table indices - -- correspond to the columns in game. - -- The items in the table either contains a TapNote object (if there is a note) - -- or be simply nil (if there are no notes) - - -- Since we only want to count the number of notes in a chord, - -- we just iterate over the table and count the ones that aren't nil. - -- Set chordsize to 1 if notes are counted separately. - - if GAMESTATE:CountNotesSeparately() then - chordsize = 1 - else - for i=1,GAMESTATE:GetCurrentStyle():ColumnsPerPlayer() do - if notes ~= nil and notes[i] ~= nil and - (notes[i]:GetTapNoteType() == 'TapNoteType_Tap' or - notes[i]:GetTapNoteType() == 'TapNoteType_HoldHead' or - notes[i]:GetTapNoteType() == 'TapNoteType_Lift') then - chordsize = chordsize+1 + local t = + Def.ActorFrame { + Name = "NPSDisplay", + InitCommand = function(self) + self:xy(MovableValues.NPSDisplayX, MovableValues.NPSDisplayY):zoom(MovableValues.NPSDisplayZoom) + if allowedCustomization then + Movable.DeviceButton_y.element = self + Movable.DeviceButton_u.element = self + Movable.DeviceButton_y.condition = enabled.NPSDisplay + Movable.DeviceButton_u.condition = enabled.NPSDisplay + Movable.DeviceButton_u.Border = self:GetChild("Border") + end + end, + OnCommand = function(self) + if allowedCustomization then + setBorderAlignment(self:GetChild("Border"), 0, 0) + setBorderToText(self:GetChild("Border"), self:GetChild("Text")) + end + end, + -- Whenever a MessageCommand is broadcasted, + -- a table contanining parameters can also be passed along. + JudgmentMessageCommand = function(self, params) + local notes = params.Notes -- this is just one of those parameters. + + local chordsize = 0 + + if params.Player == pn then + if params.Type == "Tap" then + -- The notes parameter contains a table where the table indices + -- correspond to the columns in game. + -- The items in the table either contains a TapNote object (if there is a note) + -- or be simply nil (if there are no notes) + + -- Since we only want to count the number of notes in a chord, + -- we just iterate over the table and count the ones that aren't nil. + -- Set chordsize to 1 if notes are counted separately. + if GAMESTATE:GetCurrentGame():CountNotesSeparately() then + chordsize = 1 + else + for i = 1, GAMESTATE:GetCurrentStyle():ColumnsPerPlayer() do + if notes ~= nil and notes[i] ~= nil then + chordsize = chordsize + 1 + end end end - end - -- add the note to noteTable - addNote(pn,GetTimeSinceStart(),chordsize) - lastJudgment[pn] = params.TapNoteScore + -- add the note to noteTable + addNote(pn, GetTimeSinceStart(), chordsize) + lastJudgment = params.TapNoteScore + end end - end - end; + end, + MovableBorder(100, 200, 1, 0, 0), } -- the text that will be updated by the update function. - if enabled.NPSDisplay[pn] then - t[#t+1] = LoadFont("Common Normal")..{ - Name="Text"; -- sets the name of this actor as "Text". this is a child of the actor "t". - InitCommand=function(self) - self:x(textPos[pn].X):y(textPos[pn].Y):halign(0):zoom(0.40):halign(0):valign(0):shadowlength(1):settext("0.0 NPS") - end; - BeginCommand=function(self) - if pn == PLAYER_2 then - self:x(SCREEN_WIDTH-5) - self:halign(1) + if enabled.NPSDisplay then + t[#t + 1] = + LoadFont("Common Normal") .. + { + Name = "Text", -- sets the name of this actor as "Text". this is a child of the actor "t". + InitCommand = function(self) + self:halign(0):valign(0):settext("0 NPS (Peak 0.0)") end - end; - } + } end return t -end; +end local function PLife(pn) return STATSMAN:GetCurStageStats():GetPlayerStageStats(pn):GetCurrentLife() or 0 -end; +end local function npsGraph(pn) - local t = Def.ActorFrame{ - Name = "npsGraph"..pn; - InitCommand=function(self) - self:xy(graphPos[pn].X,graphPos[pn].Y) - end + local t = + Def.ActorFrame { + Name = "NPSGraph", + InitCommand = function(self) + self:xy(MovableValues.NPSGraphX, MovableValues.NPSGraphY):zoomtoheight(MovableValues.NPSGraphHeight):zoomtowidth(MovableValues.NPSGraphWidth) + Movable.DeviceButton_i.element = self + Movable.DeviceButton_o.element = self + if allowedCustomization then + Movable.DeviceButton_i.element = self + Movable.DeviceButton_o.element = self + Movable.DeviceButton_i.condition = enabled.NPSGraph + Movable.DeviceButton_o.condition = enabled.NPSGraph + setBorderAlignment(self:GetChild("Border"), 0, 0) + end + end, } - local verts= { - {{0,0,0},Color.White} + local verts = { + {{0, 0, 0}, Color.White} } - local lifeverts= { - {{0,0,0},color("#00000000")} + local lifeverts = { + {{0, 0, 0}, color("#00000000")} } local total = 1 local peakNPS = initialPeak local curNPS = 0 - - t[#t+1] = Def.Quad{ - InitCommand=function(self) - self:zoomto(graphWidth,graphHeight) - self:xy(0,graphHeight) + t[#t + 1] = + Def.Quad { + InitCommand = function(self) + self:zoomto(graphWidth, graphHeight) + self:xy(0, graphHeight) self:diffuse(getMainColor("frame")):diffusealpha(0.4) self:horizalign(0):vertalign(2) self:fadetop(1) end } - t[#t+1] = Def.Quad{ - InitCommand=function(self) - self:zoomto(graphWidth,1) - self:xy(0,graphHeight) + t[#t + 1] = + Def.Quad { + InitCommand = function(self) + self:zoomto(graphWidth, 1) + self:xy(0, graphHeight) self:diffusealpha(0.5) self:horizalign(0) end } - t[#t+1] = Def.Quad{ - InitCommand=function(self) - self:zoomto(graphWidth,1) - self:xy(0,0) + t[#t + 1] = + Def.Quad { + InitCommand = function(self) + self:zoomto(graphWidth, 1) + self:xy(0, 0) self:diffusealpha(0.2) self:horizalign(0) end } - t[#t+1] = Def.ActorMultiVertex{ - Name= "AMV_QuadStrip", - InitCommand=function(self) + t[#t + 1] = + Def.ActorMultiVertex { + Name = "AMV_QuadStrip", + InitCommand = function(self) self:visible(true) - self:xy(graphWidth,graphHeight) - self:SetDrawState{Mode="DrawMode_LineStrip"} + self:xy(graphWidth, graphHeight) + self:SetDrawState {Mode = "DrawMode_LineStrip"} end, - BeginCommand=function(self) - self:SetDrawState{First= 1, Num= -1} + BeginCommand = function(self) + self:SetDrawState {First = 1, Num = -1} self:SetVertices(verts) + self:queuecommand("GraphUpdate") end, - GraphUpdateCommand=function(self) - self:finishtweening() - total = total+1 + GraphUpdateCommand = function(self) + total = total + 1 curNPS = getCurNPS(pn) - curJudgment = lastJudgment[pn] + curJudgment = lastJudgment if curNPS > peakNPS then -- update height if there's a new peak NPS value - for i=1,#verts do - verts[i][1][2] = verts[i][1][2]*(peakNPS/curNPS) + for i = 1, #verts do + verts[i][1][2] = verts[i][1][2] * (peakNPS / curNPS) end peakNPS = curNPS end - verts[#verts+1] = {{total*(graphWidth/maxVerts),-curNPS/peakNPS*graphHeight,0},Color.White} - if #verts>maxVerts+2 then -- Start removing unused verts. Otherwise RIP lag - table.remove(verts,1) + verts[#verts + 1] = {{total * (graphWidth / maxVerts), -curNPS / peakNPS * graphHeight, 0}, Color.White} + if #verts > maxVerts + 2 then -- Start removing unused verts. Otherwise RIP lag + table.remove(verts, 1) end self:SetVertices(verts) - self:addx(-graphWidth/maxVerts) - self:SetDrawState{First = math.max(1,#verts-maxVerts), Num=math.min(maxVerts,#verts)} - end, + self:addx(-graphWidth / maxVerts) + self:SetDrawState {First = math.max(1, #verts - maxVerts), Num = math.min(maxVerts, #verts)} + self:sleep(graphFreq) + self:queuecommand("GraphUpdate") + end } + t[#t + 1] = MovableBorder(graphWidth, graphHeight, 1, 0, 0) return t end -local t = Def.ActorFrame{ - OnCommand=function(self) - if enabled.NPSDisplay[PLAYER_1] or enabled.NPSDisplay[PLAYER_2] or - enabled.NPSGraph[PLAYER_1] or enabled.NPSGraph[PLAYER_2] then +local t = + Def.ActorFrame { + OnCommand = function(self) + if enabled.NPSDisplay or enabled.NPSGraph then self:SetUpdateFunction(Update) end end } -for _,pn in pairs(GAMESTATE:GetEnabledPlayers()) do - if enabled.NPSDisplay[pn] then - t[#t+1] = npsDisplay(pn) - end - if enabled.NPSGraph[pn] then - if not enabled.NPSDisplay[pn] then - t[#t+1] = npsDisplay(pn) - end - t[#t+1] = npsGraph(pn) +if enabled.NPSDisplay then + t[#t + 1] = npsDisplay(PLAYER_1) +end +if enabled.NPSGraph then + if not enabled.NPSDisplay then + t[#t + 1] = npsDisplay(PLAYER_1) end + t[#t + 1] = npsGraph(PLAYER_1) end -return t \ No newline at end of file +return t diff --git a/BGAnimations/ScreenGameplay overlay/pacemaker.lua b/BGAnimations/ScreenGameplay overlay/pacemaker.lua index 003bc176..4e315945 100644 --- a/BGAnimations/ScreenGameplay overlay/pacemaker.lua +++ b/BGAnimations/ScreenGameplay overlay/pacemaker.lua @@ -12,7 +12,7 @@ local frameX = SCREEN_WIDTH-frameWidth local frameY = 0 local barY = 430-- Starting point/bottom of graph -local barCount = GAMESTATE:IsCourseMode() and 2 or 3 -- Number of graphs +local barCount = 3 -- Number of graphs local barWidth = 0.65 local barTrim = 0 -- Final width of each graph = ((frameWidth/barCount)*barWidth) - barTrim local barHeight = 350 -- Max Height of graphs @@ -25,14 +25,9 @@ local enabled = GAMESTATE:GetNumPlayersEnabled() == 1 local player = GAMESTATE:GetEnabledPlayers()[1] if player == PLAYER_1 then - ghostType = playerConfig:get_data(pn_to_profile_slot(player)).GhostScoreType; -- 0 = off,1 = DP,2 = PS,3 = MIGS - target = playerConfig:get_data(pn_to_profile_slot(player)).GhostTarget/100; -- target score from 0% to 100%. + ghostType = playerConfig:get_data(pn_to_profile_slot(player)).GhostScoreType -- 0 = off,1 = DP,2 = PS,3 = MIGS + target = playerConfig:get_data(pn_to_profile_slot(player)).GhostTarget/100 -- target score from 0% to 100%. enabled = enabled and playerConfig:get_data(pn_to_profile_slot(player)).PaceMaker -elseif player == PLAYER_2 then - ghostType = playerConfig:get_data(pn_to_profile_slot(player)).GhostScoreType; -- 0 = off,1 = DP,2 = PS,3 = MIGS - target = playerConfig:get_data(pn_to_profile_slot(player)).GhostTarget/100; -- target score from 0% to 100%. - enabled = enabled and playerConfig:get_data(pn_to_profile_slot(player)).PaceMaker - frameX = 0 end local profile = GetPlayerOrMachineProfile(player) @@ -82,7 +77,7 @@ local function ghostScoreGraph(index,scoreType,color) self:zoomto(frameWidth/barCount*barWidth,1) self:valign(1) self:diffuse(color):diffusealpha(0.7) - end; + end, SetCommand = function(self) local curScore = getCurScoreGD(player,scoreType) local maxScore = getMaxScoreST(player,scoreType) @@ -91,7 +86,7 @@ local function ghostScoreGraph(index,scoreType,color) else self:zoomy(math.max(1,barHeight*(curScore/maxScore))) end - end; + end, GhostScoreMessageCommand = function(self) self:queuecommand("Set") end } @@ -110,7 +105,7 @@ local function ghostScoreGraph(index,scoreType,color) self:zoom(0.35):maxwidth(((frameWidth*0.8)-2)/0.35) self:halign(0) self:diffuse(color) - end; + end, BeginCommand = function(self) if getCurRate() == "1.0x" or not themeConfig:get_data().global.RateSort then self:settextf("%s Best",getScoreTypeText(ghostType)) @@ -126,7 +121,7 @@ local function ghostScoreGraph(index,scoreType,color) self:zoom(0.35):maxwidth(25/0.35) self:halign(1) self:settext(0) - end; + end, SetCommand = function(self) local score if isGhostDataValid(player,hsTable[1]) then @@ -135,7 +130,7 @@ local function ghostScoreGraph(index,scoreType,color) score = getBestScore(player,0,scoreType) end self:settext(score) - end; + end, GhostScoreMessageCommand = function(self) self:queuecommand("Set") end } @@ -156,7 +151,7 @@ local function currentScoreGraph(index,scoreType,color) self:zoomto(frameWidth/barCount*barWidth,1) self:valign(1) self:diffuse(color):diffusealpha(0.7) - end; + end, SetCommand = function(self) local curScore = getCurScoreST(player,scoreType) local maxScore = getMaxScoreST(player,scoreType) @@ -164,8 +159,8 @@ local function currentScoreGraph(index,scoreType,color) self:zoomy(1) else self:zoomy(math.max(1,barHeight*(curScore/maxScore))) - end; - end; + end + end, JudgmentMessageCommand = function(self) self:queuecommand("Set") end } @@ -184,9 +179,9 @@ local function currentScoreGraph(index,scoreType,color) self:zoom(0.35):maxwidth(((frameWidth*0.8)-2)/0.35) self:halign(0) self:diffuse(color) - end; + end, BeginCommand = function(self) - local text = profile:GetDisplayName(); + local text = profile:GetDisplayName() if text == "" then self:settext("Machine Profile") else @@ -201,11 +196,11 @@ local function currentScoreGraph(index,scoreType,color) self:zoom(0.35):maxwidth(25/0.35) self:halign(1) self:settext(0) - end; + end, SetCommand = function(self) local curScore = getCurScoreST(player,scoreType) self:settext(curScore) - end; + end, JudgmentMessageCommand = function(self) self:queuecommand("Set") end } @@ -227,7 +222,7 @@ local function avgScoreGraph(index,scoreType,color) self:zoomto(frameWidth/barCount*barWidth,1) self:valign(1) self:diffuse(color):diffusealpha(0.2) - end; + end, SetCommand = function(self) local curScore = getCurScoreST(player,scoreType) local curMaxScore = getCurMaxScoreST(player,scoreType) @@ -236,7 +231,7 @@ local function avgScoreGraph(index,scoreType,color) else self:zoomy(math.max(1,barHeight*(curScore/curMaxScore))) end - end; + end, JudgmentMessageCommand = function(self) self:queuecommand("Set") end } @@ -259,7 +254,7 @@ local function bestScoreGraph(index,scoreType,color) self:zoomto(frameWidth/barCount*barWidth,1) self:valign(1) self:diffuse(color):diffusealpha(0.2) - end; + end, BeginCommand = function(self) local bestScore = 0 if themeConfig:get_data().global.RateSort then @@ -282,7 +277,7 @@ local function bestScoreGraph(index,scoreType,color) self:xy((1+(2*(index-1)))*(frameWidth/(barCount*2)),frameY+barY-12) self:zoom(0.35):maxwidth(frameWidth/barCount*barWidth/0.35) self:diffusealpha(0) - end; + end, BeginCommand = function(self) local bestScore = 0 if themeConfig:get_data().global.RateSort then @@ -323,7 +318,7 @@ local function targetScoreGraph(index,scoreType,color) self:zoomto(frameWidth/barCount*barWidth,1) self:valign(1) self:diffuse(color):diffusealpha(0.7) - end; + end, SetCommand = function(self) local curScore = math.ceil(getCurMaxScoreST(player,scoreType)*target) local maxScore = getMaxScoreST(player,scoreType) @@ -332,7 +327,7 @@ local function targetScoreGraph(index,scoreType,color) else self:zoomy(math.max(1,barHeight*(curScore/maxScore))) end - end; + end, JudgmentMessageCommand = function(self) self:queuecommand("Set") end } @@ -352,7 +347,7 @@ local function targetScoreGraph(index,scoreType,color) self:halign(0) self:diffuse(color) self:settextf("%s %0.2f%%",getScoreTypeText(ghostType),target*100) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -361,16 +356,16 @@ local function targetScoreGraph(index,scoreType,color) self:zoom(0.35):maxwidth(25/0.35) self:halign(1) self:settext(0) - end; + end, SetCommand = function(self) local curScore = math.ceil(getCurMaxScoreST(player,scoreType)*target) self:settext(curScore) - end; + end, JudgmentMessageCommand = function(self) self:queuecommand("Set") end } return t -end; +end -- Represents the total target score for the specified scoreType @@ -386,7 +381,7 @@ local function targetMaxGraph(index,scoreType,color) self:zoomto(frameWidth/barCount*barWidth,1) self:valign(1) self:diffuse(color):diffusealpha(0.2) - end; + end, BeginCommand = function(self) local maxScore = getMaxScoreST(player,scoreType) self:smooth(1.5) @@ -403,7 +398,7 @@ local function targetMaxGraph(index,scoreType,color) self:xy((1+(2*(index-1)))*(frameWidth/(barCount*2)),frameY+barY-12) self:zoom(0.35):maxwidth(frameWidth/barCount*barWidth/0.35) self:diffusealpha(0) - end; + end, BeginCommand = function(self) local maxScore = getMaxScoreST(player,scoreType) self:smooth(1.5) @@ -439,7 +434,7 @@ local function markers(scoreType,showMessage) self:y(barY-(barHeight*v)) self:zoomto(frameWidth,2) self:halign(0) - end; + end, JudgmentMessageCommand = function(self) local percent = getCurScoreST(player,scoreType)/getMaxScoreST(player,scoreType) if percent >= v then @@ -456,7 +451,7 @@ local function markers(scoreType,showMessage) self:zoom(0.3) self:halign(0):valign(1) self:settext(getGradeStrings(k)) - end; + end, JudgmentMessageCommand = function(self) local percent = getCurScoreST(player,scoreType)/getMaxScoreST(player,scoreType) if percent >= v then @@ -474,7 +469,7 @@ local function markers(scoreType,showMessage) return t -end; +end -- Text showing life/judge setting @@ -489,7 +484,7 @@ local function lifejudge() self:xy(2,15) self:zoom(0.4) self:halign(0):valign(1) - end; + end, BeginCommand = function(self) self:settext(THEME:GetString("ScreenGameplay","PacemakerTimingDifficulty")..":") end @@ -500,7 +495,7 @@ local function lifejudge() self:xy(2,28) self:zoom(0.4) self:halign(0):valign(1) - end; + end, BeginCommand = function(self) self:settext(THEME:GetString("ScreenGameplay","PacemakerLifeDifficulty")..":") end @@ -512,7 +507,7 @@ local function lifejudge() self:xy(frameWidth-5,15) self:zoom(0.4) self:halign(1):valign(1) - end; + end, BeginCommand = function(self) self:settext(GetTimingDifficulty()) end @@ -523,7 +518,7 @@ local function lifejudge() self:xy(frameWidth-5,28) self:zoom(0.4) self:halign(1):valign(1) - end; + end, BeginCommand = function(self) self:settext(GetLifeDifficulty()) end @@ -550,11 +545,8 @@ if enabled then t[#t+1] = avgScoreGraph(1,ghostType,getPaceMakerColor("Current")) t[#t+1] = currentScoreGraph(1,ghostType,getPaceMakerColor("Current")) - -- Remove Best Graph for Course modes. - if not GAMESTATE:IsCourseMode() then - t[#t+1] = ghostScoreGraph(2,ghostType,getPaceMakerColor("Best")) - t[#t+1] = bestScoreGraph(2,ghostType,getPaceMakerColor("Best")) - end + t[#t+1] = ghostScoreGraph(2,ghostType,getPaceMakerColor("Best")) + t[#t+1] = bestScoreGraph(2,ghostType,getPaceMakerColor("Best")) t[#t+1] = targetMaxGraph(math.min(barCount,3),ghostType,getPaceMakerColor("Target")) t[#t+1] = targetScoreGraph(math.min(barCount,3),ghostType,getPaceMakerColor("Target")) @@ -562,7 +554,7 @@ if enabled then t[#t+1] = markers(ghostType,true) t[#t+1] = lifejudge() -end; +end return t \ No newline at end of file diff --git a/BGAnimations/ScreenGameplay overlay/progressbar.lua b/BGAnimations/ScreenGameplay overlay/progressbar.lua index 7f7a0bec..af62118d 100644 --- a/BGAnimations/ScreenGameplay overlay/progressbar.lua +++ b/BGAnimations/ScreenGameplay overlay/progressbar.lua @@ -7,12 +7,17 @@ local bareBone = isBareBone() local width = SCREEN_WIDTH local height = 15 local frameX = SCREEN_CENTER_X -local bottomModifier = -20; -- Negative value, how far up -local topModifier = 15; -- Positive value, how far down +local bottomModifier = -20 -- Negative value, how far up +local topModifier = 15 -- Positive value, how far down local frameY = SCREEN_HEIGHT-height/2 local opacity = 1 --======================================= +local location = themeConfig:get_data().global.ProgressBar -- 1 is bottom, 2 is top + +if location == 2 then + frameY = height/2 +end local t = Def.ActorFrame { OnCommand = function(self) @@ -21,51 +26,51 @@ local t = Def.ActorFrame { } t[#t+1] = Def.Quad{ - Name="ProgressBG"; + Name="ProgressBG", InitCommand=function(self) self:x(width/2):zoomto(width,height):halign(1):diffuse(color("#000000")):diffusealpha(opacity) - end; + end } t[#t+1] = Def.Quad{ - Name="ProgressFG"; + Name="ProgressFG", InitCommand=function(self) self:x(-width/2):zoomto(0,height):halign(0):diffuse(getMainColor('highlight')):diffusealpha(opacity) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { - Name="Song Name"; + Name="Song Name", InitCommand=function(self) self:zoom(0.35):maxwidth((width-65)/0.35) - end; + end, SetCommand=function(self) local song = GAMESTATE:GetCurrentSong() self:settextf("%s // %s",song:GetDisplayMainTitle(),song:GetDisplayArtist()) - end; - BeginCommand = function(self) self:playcommand('Set') end; - CurrentSongChangedMessageCommand = function(self) self:playcommand('Set') end; + end, + BeginCommand = function(self) self:playcommand('Set') end, + CurrentSongChangedMessageCommand = function(self) self:playcommand('Set') end } t[#t+1] = LoadFont("Common Normal") .. { - Name="CurrentTime"; + Name="CurrentTime", InitCommand=function(self) self:x(-width/2+5):halign(0):zoom(0.35):settext("0:00") end } t[#t+1] = LoadFont("Common Normal") .. { - Name="TotalTime"; + Name="TotalTime", InitCommand=function(self) self:x(width/2-5):halign(1):zoom(0.35) - end; + end, SetCommand=function(self) local song = GAMESTATE:GetCurrentSong() self:settext(SecondsToMSSMsMs(song:GetStepsSeconds()/GAMESTATE:GetSongOptionsObject('ModsLevel_Preferred'):MusicRate())) - end; - BeginCommand = function(self) self:playcommand('Set') end; - CurrentSongChangedMessageCommand = function(self) self:playcommand('Set') end; + end, + BeginCommand = function(self) self:playcommand('Set') end, + CurrentSongChangedMessageCommand = function(self) self:playcommand('Set') end } @@ -78,23 +83,23 @@ local function getMusicProgress() songPosition = songPosition/rate songLength = math.max(1,songLength/rate) return math.min(1,math.max(0,songPosition/songLength)) -end; +end local function getCurrentTime() local rate = GAMESTATE:GetSongOptionsObject('ModsLevel_Preferred'):MusicRate() local time = GAMESTATE:GetSongPosition():GetMusicSeconds() return SecondsToMSSMsMs(math.max(0,time/rate or 0)) -end; +end local function Update(self) t.InitCommand=function(self) self:SetUpdateFunction(Update) - end; + end, self:GetChild("ProgressFG"):zoomx(width*getMusicProgress()) if not bareBone then self:GetChild("CurrentTime"):settext(getCurrentTime()) end -end; +end t.InitCommand=function(self) if barPosition ~= 0 then @@ -105,4 +110,4 @@ t.InitCommand=function(self) end -return t; \ No newline at end of file +return t \ No newline at end of file diff --git a/BGAnimations/ScreenGameplay overlay/scoretracking.lua b/BGAnimations/ScreenGameplay overlay/scoretracking.lua index 3806570e..7ecfbd03 100644 --- a/BGAnimations/ScreenGameplay overlay/scoretracking.lua +++ b/BGAnimations/ScreenGameplay overlay/scoretracking.lua @@ -1,6 +1,4 @@ -- Most of the scoretracking function calls and message broadcasting are done here. - -local bareBone = isBareBone() local startFlag = false local fcFlag = false local fcFlagDelay = 0.5 -- Minimum delay after lastSecond before broadcasting FC message. @@ -32,7 +30,7 @@ end local t = Def.ActorFrame{ InitCommand = function(self) self:SetUpdateFunction(Update) - end; + end, -- Reset flags and first/last second at the beginning of each song. CurrentSongChangedMessageCommand = function(self) firstSecond = GAMESTATE:GetCurrentSong():GetFirstSecond() diff --git a/BGAnimations/ScreenGameplay overlay/title.lua b/BGAnimations/ScreenGameplay overlay/title.lua index d7a6f703..37f0eab8 100644 --- a/BGAnimations/ScreenGameplay overlay/title.lua +++ b/BGAnimations/ScreenGameplay overlay/title.lua @@ -9,12 +9,12 @@ local t = Def.ActorFrame{ InitCommand = function(self) self:xy(SCREEN_CENTER_X,SCREEN_CENTER_Y-50) self:diffusealpha(0) - end; + end, CurrentSongChangedMessageCommand = function(self) self:easeOut(1) self:diffusealpha(0.8) self:xy(SCREEN_CENTER_X,SCREEN_CENTER_Y-60) - end; + end, SongStartingMessageCommand = function(self) self:stoptweening() self:smooth(0.5) @@ -29,11 +29,11 @@ t[#t+1] = Def.Quad{ self:zoomto(bannerWidth+borderWidth*4,bannerHeight+borderWidth*4+30) self:diffuse(color("#000000")) self:diffusealpha(0) - end; + end, CurrentSongChangedMessageCommand = function(self) self:diffuse(getDifficultyColor(GAMESTATE:GetHardestStepsDifficulty())) - end; -}; + end +} t[#t+1] = Def.Quad{ InitCommand = function(self) @@ -41,17 +41,21 @@ t[#t+1] = Def.Quad{ self:zoomto(bannerWidth+borderWidth*2,bannerHeight+borderWidth*2+30) self:diffuse(color("#000000")) self:diffusealpha(0.8) - end; + end } -t[#t+1] = Def.Banner{ +t[#t+1] = Def.Sprite { CurrentSongChangedMessageCommand = function(self) local song = GAMESTATE:GetCurrentSong() if song then - self:LoadFromSong(song) + local bnpath = song:GetBannerPath() + if not bnpath then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) end self:scaletoclipped(bannerWidth,bannerHeight) - end; + end } t[#t+1] = LoadFont("Common Bold") .. { @@ -60,10 +64,10 @@ t[#t+1] = LoadFont("Common Bold") .. { self:zoom(0.6) self:diffusealpha(1) self:maxwidth(bannerWidth/0.6) - end; + end, CurrentSongChangedMessageCommand = function(self) self:settext(GAMESTATE:GetCurrentSong():GetDisplayMainTitle()) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { @@ -72,10 +76,10 @@ t[#t+1] = LoadFont("Common Normal") .. { self:zoom(0.4) self:diffusealpha(1) self:maxwidth(bannerWidth/0.4) - end; + end, CurrentSongChangedMessageCommand = function(self) self:settext(GAMESTATE:GetCurrentSong():GetDisplayArtist()) - end; + end } diff --git a/BGAnimations/ScreenGameplay underlay/SpeedChange.lua b/BGAnimations/ScreenGameplay underlay/SpeedChange.lua index 7f75de12..6d2a8529 100644 --- a/BGAnimations/ScreenGameplay underlay/SpeedChange.lua +++ b/BGAnimations/ScreenGameplay underlay/SpeedChange.lua @@ -15,22 +15,20 @@ end local increment = get_speed_increment() local t = Def.ActorFrame{ - Name="SpeedChange"; + Name="SpeedChange", CodeMessageCommand = function(self, params) local pn = params.PlayerNumber - local po = GAMESTATE:GetPlayerState(pn):GetPlayerOptions("ModsLevel_Preferred"); - local os = GAMESTATE:GetPlayerState(pn):GetPlayerOptionsString("ModsLevel_Preferred"); + local po = GAMESTATE:GetPlayerState(pn):GetPlayerOptions("ModsLevel_Preferred") + local os = GAMESTATE:GetPlayerState(pn):GetPlayerOptionsString("ModsLevel_Preferred") local speedType = 1 -- 1 = x, 2 = c, 3 = m local xSpeed local cSpeed local avatarOption - local topScreen = SCREENMAN:GetTopScreen(); + local topScreen = SCREENMAN:GetTopScreen() --Grab actors for the optionlines beside the profile avatar if pn == PLAYER_1 and GAMESTATE:IsPlayerEnabled(PLAYER_1) then avatarOption = topScreen:GetChildren().Overlay:GetChildren().Avatars:GetChildren().P1Avatar:GetChildren().P1AvatarOption - elseif pn == PLAYER_2 and GAMESTATE:IsPlayerEnabled(PLAYER_2) then - avatarOption = topScreen:GetChildren().Overlay:GetChildren().Avatars:GetChildren().P2Avatar:GetChildren().P2AvatarOption end --Check type of speedmod used. if something goes wrong, default to xmod. @@ -46,7 +44,7 @@ local t = Def.ActorFrame{ else speedType = 1 xSpeed = 1 - end; + end --increment speedmods when a certain key is pressed (EffectUp/EffectDown) if params.Name == "SpeedUp" then @@ -56,7 +54,7 @@ local t = Def.ActorFrame{ po:MMod(math.max(10,po:MMod()+increment)) else po:XMod(math.max(0.1,po:XMod()+(increment/100))) - end; + end elseif params.Name == "SpeedDown" then if speedType == 2 then po:CMod(math.max(10,po:CMod()-increment)) @@ -64,17 +62,17 @@ local t = Def.ActorFrame{ po:MMod(math.max(10,po:MMod()-increment)) else po:XMod(math.max(0.1,po:XMod()-(increment/100))) - end; + end end --Set the speedmod and set the player's option text. if GAMESTATE:IsPlayerEnabled(pn) then - GAMESTATE:GetPlayerState(pn):SetPlayerOptions("ModsLevel_Preferred",GAMESTATE:GetPlayerState(pn):GetPlayerOptionsString("ModsLevel_Preferred")); + GAMESTATE:GetPlayerState(pn):SetPlayerOptions("ModsLevel_Preferred",GAMESTATE:GetPlayerState(pn):GetPlayerOptionsString("ModsLevel_Preferred")) avatarOption:settext(GAMESTATE:GetPlayerState(pn):GetPlayerOptionsString('ModsLevel_Current')) - end; + end - end; -}; + end +} return t \ No newline at end of file diff --git a/BGAnimations/ScreenGameplay underlay/default.lua b/BGAnimations/ScreenGameplay underlay/default.lua index 0a98cf44..90ada7e4 100644 --- a/BGAnimations/ScreenGameplay underlay/default.lua +++ b/BGAnimations/ScreenGameplay underlay/default.lua @@ -1,10 +1,20 @@ -local t = Def.ActorFrame{} +local playeroptions = GAMESTATE:GetPlayerState(PLAYER_1):GetPlayerOptions("ModsLevel_Preferred") +playeroptions:Mini(2 - playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).ReceptorSize / 50) +local profile = PROFILEMAN:GetProfile(PLAYER_1) +local replaystate = GAMESTATE:GetPlayerState(PLAYER_1):GetPlayerController() == "PlayerController_Replay" +if profile:IsCurrentChartPermamirror() and not replaystate then -- turn on mirror if song is flagged as perma mirror + playeroptions:Mirror(true) +end + +setMovableKeymode(getCurrentKeyMode()) +local t = Def.ActorFrame{} t[#t+1] = Def.Quad{ InitCommand=function(self) self:xy(0,0):halign(0):valign(0):zoomto(SCREEN_WIDTH,30):diffuse(color("#00000099")):fadebottom(0.8) - end; -}; + end +} + return t \ No newline at end of file diff --git a/BGAnimations/ScreenGoalManager decorations/default.lua b/BGAnimations/ScreenGoalManager decorations/default.lua new file mode 100644 index 00000000..a8235dec --- /dev/null +++ b/BGAnimations/ScreenGoalManager decorations/default.lua @@ -0,0 +1,3 @@ +local t = Def.ActorFrame{} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenPlaylistInfo in.lua b/BGAnimations/ScreenGoalManager out.lua similarity index 100% rename from BGAnimations/ScreenPlaylistInfo in.lua rename to BGAnimations/ScreenGoalManager out.lua diff --git a/BGAnimations/ScreenGoalManager overlay/default.lua b/BGAnimations/ScreenGoalManager overlay/default.lua new file mode 100644 index 00000000..bd425960 --- /dev/null +++ b/BGAnimations/ScreenGoalManager overlay/default.lua @@ -0,0 +1,963 @@ +local profile = GetPlayerOrMachineProfile(PLAYER_1) +profile:SetFromAll() +local maxGoals = 11 +local curPage = 1 +local song = GAMESTATE:GetCurrentSong() +local goaltable = profile:GetGoalTable() +local maxPages = math.ceil(#goaltable/maxGoals) +local inDetail = false + +local function updateGoalsFromData() + profile:SortByName() + goaltable = profile:GetGoalTable() + GHETTOGAMESTATE:resetGoalTable() + curPage = 1 + maxPages = math.ceil(#goaltable/maxGoals) +end + +local function byAchieved(scoregoal) + if not scoregoal or scoregoal:IsAchieved() then + return getMainColor("positive") + end + if scoregoal:IsVacuous() then + return color("#ffcccc") + end + return color("#cccccc") +end + +local function movePage(n) + if maxPages > 1 then + if n > 0 then + curPage = ((curPage+n-1) % maxPages + 1) + else + curPage = ((curPage+n+maxPages-1) % maxPages+1) + end + end + MESSAGEMAN:Broadcast("UpdateList") +end + +local function input(event) + + if event.type == "InputEventType_FirstPress" then + if event.button == "Back" or event.button == "Start" then + SCREENMAN:GetTopScreen():Cancel() + elseif event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + elseif event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + elseif event.button == "MenuLeft" then + movePage(-1) + elseif event.button == "MenuRight" then + movePage(1) + end + end + + + return false +end + +local top +local leftSectionWidth = 300 +local leftSectionHeight = SCREEN_HEIGHT - 60 +local leftUpperSectionHeight = leftSectionHeight / 3 +local leftLowerSectionHeight = SCREEN_HEIGHT / 1.5 - 10 +local rightSectionWidth = SCREEN_WIDTH - 330 +local rightSectionHeight = SCREEN_HEIGHT - 60 + +local verticalSpacing = 7 +local horizontalSpacing = 10 + + +local t = Def.ActorFrame { + OnCommand = function(self) + everything = self + top = SCREENMAN:GetTopScreen() + top:AddInputCallback(input) + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end, + DFRFinishedMessageCommand = function(self) -- not sure this would even normally happen on this screen but just in case + profile:SetFromAll() + updateGoalsFromData() + self:queuecommand("UpdateList") + end +} + +local boxHeight = 20 +local numBoxWidth = leftSectionWidth / 2 + +t[#t+1] = LoadActor("../_mouse") + +t[#t+1] = LoadActor("../_frame") + +local frameWidth = 430 +local frameHeight = 340 + +-- The upper left container (Minimal Profile Card) +local function upperLeftContainer() + + local t = Def.ActorFrame { + Name = "ProfileCard", + InitCommand = function(self) + self:xy(10,30) + end, + + Def.Quad { + InitCommand = function(self) + self:halign(0):valign(0) + self:zoomto(300,100) + self:diffuse(color(colorConfig:get_data().main.frame)):diffusealpha(0.85) + end + } + } + + t[#t+1] = LoadActor("../ScreenPlayerProfile decorations/avatar") .. { + InitCommand = function(self) + self:xy(50,50) + end + } + + t[#t+1] = LoadFont("Common BLarge") .. { + InitCommand = function(self) + self:xy(100,25) + self:zoom(0.35) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:queuecommand("Set") + end, + SetCommand = function(self) + self:settext(getCurrentUsername(PLAYER_1)) + end + } + + t[#t+1] = LoadActor("../ScreenPlayerProfile decorations/expbar") .. { + InitCommand = function(self) + self:xy(100,55) + end + } + + return t +end + +-- The lower left container (The Tag Editor) +local function lowerLeftContainer() + + local goalIndex -- im really killing the scope here haha + + local t = Def.ActorFrame { + Name = "EditorContainer", + InitCommand = function(self) + self:xy(10, leftUpperSectionHeight) + end, + HideGoalDetailMessageCommand = function(self) + end, + + -- The container quad + Def.Quad { + InitCommand = function(self) + self:zoomto(leftSectionWidth, leftLowerSectionHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.85) + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Edit Goal") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(leftSectionWidth/2,25) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Title") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(leftSectionWidth/2,50) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("MSD") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(leftSectionWidth/2,75) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Current PB") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(leftSectionWidth/2,34) + self:zoom(0.35) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("") + self:maxwidth(leftSectionWidth * 2.3) + end, + SetCommand = function(self) + local ck = goaltable[goalIndex]:GetChartKey() + local goalsong = SONGMAN:GetSongByChartKey(ck) + if goalsong then + self:settextf("%s",goalsong:GetDisplayMainTitle()) + else + self:settextf("%s", ck) + end + end, + ShowGoalDetailMessageCommand = function(self, params) + goalIndex = params.goalIndex + self:queuecommand("Set") + end, + HideGoalDetailMessageCommand = function(self) + self:settext("") + end, + UpdateGoalDetailsMessageCommand = function(self) + self:queuecommand("Set") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(leftSectionWidth/2,59) + self:zoom(0.35) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("") + self:maxwidth(leftSectionWidth * 2.3) + end, + SetCommand = function(self) + local ck = goaltable[goalIndex]:GetChartKey() + local goalsong = SONGMAN:GetSongByChartKey(ck) + local goalsteps = SONGMAN:GetStepsByChartKey(ck) + if goalsteps and goaltable[goalIndex] then + local msd = goalsteps:GetMSD(goaltable[goalIndex]:GetRate(), 1) + self:settextf("%5.1f", msd) + self:diffuse(byMSD(msd)) + else + self:settext("??") + end + end, + ShowGoalDetailMessageCommand = function(self, params) + goalIndex = params.goalIndex + self:queuecommand("Set") + end, + HideGoalDetailMessageCommand = function(self) + self:settext("") + end, + UpdateGoalDetailsMessageCommand = function(self) + self:queuecommand("Set") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(leftSectionWidth/2,84) + self:zoom(0.35) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("") + self:maxwidth(leftSectionWidth * 2.3) + end, + SetCommand = function(self) + local pb = goaltable[goalIndex]:GetPBUpTo() + if pb then + if pb:GetMusicRate() < goaltable[goalIndex]:GetRate() then + local ratestring = string.format("%.2f", pb:GetMusicRate()):gsub("%.?0$", "") .. "x" + self:settextf("Best: %5.2f%% (%s)", pb:GetWifeScore() * 100, ratestring) + else + self:settextf("Best: %5.2f%%", pb:GetWifeScore() * 100) + end + self:diffuse(getGradeColor(pb:GetWifeGrade())) + self:visible(true) + else + self:settextf("(Best: %5.2f%%)", 0) + self:diffuse(byAchieved(goaltable[goalIndex])) + end + end, + ShowGoalDetailMessageCommand = function(self, params) + goalIndex = params.goalIndex + self:queuecommand("Set") + end, + HideGoalDetailMessageCommand = function(self) + self:settext("") + end, + UpdateGoalDetailsMessageCommand = function(self) + self:queuecommand("Set") + end + } + } + local function rateChangeButton() + local topRowFrameWidth = SCREEN_WIDTH - 20 + local topRowFrameHeight = 40 + local frameWidth = 150 + local frameHeight = 25 + local goalIndex + local t = Def.ActorFrame { + Name = "RateChangeButton", + InitCommand = function(self) + self:xy(leftSectionWidth/2 + frameWidth/2,150) + end, + ShowGoalDetailMessageCommand = function(self, params) + goalIndex = params.goalIndex + self:queuecommand("Set") + end + } + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(-frameWidth/2, -22) + self:zoom(0.35) + self:settext("Change Rate") + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, 25) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(1) + end + } + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:x(-frameWidth/2) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:faderight(0.5) + end, + TopPressedCommand = function(self, params) + if inDetail then + goaltable[goalIndex]:SetRate(goaltable[goalIndex]:GetRate() - 0.05) + MESSAGEMAN:Broadcast("UpdateGoalDetails") + self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + end + } + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:fadeleft(0.5) + end, + TopPressedCommand = function(self, params) + if inDetail then + goaltable[goalIndex]:SetRate(goaltable[goalIndex]:GetRate() + 0.05) + MESSAGEMAN:Broadcast("UpdateGoalDetails") + self:GetParent():GetChild("TriangleRight"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + end + } + + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleLeft", + InitCommand = function(self) + self:zoom(0.15) + self:x(-frameWidth + 10) + self:diffusealpha(0.8) + self:rotationz(-90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleRight", + InitCommand = function(self) + self:zoom(0.15) + self:x(-10) + self:diffusealpha(0.8) + self:rotationz(90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:x(-frameWidth/2) + self:zoom(0.3) + self:queuecommand("Set") + end, + SetCommand = function(self, params) + if goaltable[goalIndex] then + local ratestring = string.format("%.2f", goaltable[goalIndex]:GetRate()):gsub("%.?0$", "") .. "x" + self:settext(ratestring) + end + end, + UpdateGoalDetailsMessageCommand = function(self) + self:playcommand("Set") + end, + HideGoalDetailMessageCommand = function(self) + self:settext("") + end + } + + return t + end + + local function percentChangeButton() + local topRowFrameWidth = SCREEN_WIDTH - 20 + local topRowFrameHeight = 40 + local frameWidth = 150 + local frameHeight = 25 + local goalIndex + local t = Def.ActorFrame { + Name = "PercentChangeButton", + InitCommand = function(self) + self:xy(leftSectionWidth/2 + frameWidth/2,200) + end, + ShowGoalDetailMessageCommand = function(self, params) + goalIndex = params.goalIndex + self:queuecommand("Set") + end + } + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(-frameWidth/2, -22) + self:zoom(0.35) + self:settext("Change Goal Percent") + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, 25) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(1) + end + } + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:x(-frameWidth/2) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:faderight(0.5) + end, + TopPressedCommand = function(self, params) + if inDetail then + goaltable[goalIndex]:SetPercent(goaltable[goalIndex]:GetPercent() - 0.01) + MESSAGEMAN:Broadcast("UpdateGoalDetails") + self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + end + } + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:fadeleft(0.5) + end, + TopPressedCommand = function(self, params) + if inDetail then + goaltable[goalIndex]:SetPercent(goaltable[goalIndex]:GetPercent() + 0.01) + MESSAGEMAN:Broadcast("UpdateGoalDetails") + self:GetParent():GetChild("TriangleRight"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + end + } + + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleLeft", + InitCommand = function(self) + self:zoom(0.15) + self:x(-frameWidth + 10) + self:diffusealpha(0.8) + self:rotationz(-90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleRight", + InitCommand = function(self) + self:zoom(0.15) + self:x(-10) + self:diffusealpha(0.8) + self:rotationz(90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:x(-frameWidth/2) + self:zoom(0.3) + self:queuecommand("Set") + end, + SetCommand = function(self, params) + if goaltable[goalIndex] then + local perc = math.floor(goaltable[goalIndex]:GetPercent() * 10000) / 100 + if perc < 99 then + self:settextf("%.f%%", perc) + else + self:settextf("%.2f%%", perc) + end + end + end, + UpdateGoalDetailsMessageCommand = function(self) + self:playcommand("Set") + end, + HideGoalDetailMessageCommand = function(self) + self:settext("") + end + } + + return t + end + + local function deleteButton() + local goalIndex + local t = Def.ActorFrame { + quadButton(6) .. { + InitCommand = function(self) + self:xy(15, leftLowerSectionHeight/2 - 30) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(numBoxWidth + 15, 35) + end, + ShowGoalDetailMessageCommand = function(self, params) + goalIndex = params.goalIndex + end, + TopPressedCommand = function(self) + if goaltable[goalIndex] and inDetail then + goaltable[goalIndex]:Delete() + profile:SetFromAll() + updateGoalsFromData() + MESSAGEMAN:Broadcast("HideGoalDetail") + MESSAGEMAN:Broadcast("UpdateList") + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + end + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(15 + (numBoxWidth+15)/2,leftLowerSectionHeight/2 - 30) + self:zoom(0.4) + self:settext("Delete Goal") + end + } + } + return t + end + + t[#t+1] = deleteButton() .. { + InitCommand = function(self) + self:xy(-15 + leftSectionWidth/2 - (numBoxWidth+15)/2, leftLowerSectionHeight/2) + end + } + + t[#t+1] = rateChangeButton() + + t[#t+1] = percentChangeButton() + + return t +end + +-- The right container (The Tags Menu) +local function rightContainer() + + local boxHeight = 25 + local boxWidth = rightSectionWidth - 40 + + local t = Def.ActorFrame { + Name = "GoalContainer", + InitCommand = function(self) + self:xy(20 + leftSectionWidth,30) + MESSAGEMAN:Broadcast("UpdateList") + end, + + -- The container quad + Def.Quad { + InitCommand = function (self) + self:zoomto(rightSectionWidth,rightSectionHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.85) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() then + movePage(1) + end + end, + MouseRightClickMessageCommand = function(self) + if inDetail and isOver(self) then + self:sleep(0.05) + self:queuecommand("DelayedHide") + end + end, + DelayedHideCommand = function(self) + MESSAGEMAN:Broadcast("HideGoalDetail") + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Manage Goals") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(7,25) + self:zoom(0.35) + self:halign(0) + self:valign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Left click a Goal to jump to the song for it. Right click a Goal to edit it in the left section.") + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(100,10) + self:zoom(0.35) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Create a goal for a song by pressing Ctrl + G while on it.") + end + } + } + + -- this is copied straight from the filter screen which is copied from the downloader screen + -- theming is so easy lol + local function goalItem(i) + local goalIndex = (curPage-1)*10+i + local goalsong + local goalsteps + local ck + local theDetail + + local r = Def.ActorFrame{ + Name = "GoalItem"..i, + InitCommand = function(self) + self:diffusealpha(0) + self:xy(25, 30 + ((i-1) *(boxHeight+verticalSpacing)-10)) + self:playcommand("Show") + end, + ShowCommand = function(self) + self:y(30 + ((i-1)*(boxHeight+verticalSpacing)-10)) + self:diffusealpha(0) + self:finishtweening() + self:sleep((i-1)*0.01) + self:easeOut(0.3) + self:y(30 + ((i-1)*(boxHeight+verticalSpacing)+25)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:finishtweening() + self:easeOut(0.2) + self:diffusealpha(0) + end, + UpdateListMessageCommand = function(self) + goalIndex = (curPage-1)*10+i + theDetail = false + inDetail = false + if goaltable[goalIndex] ~= nil then + ck = goaltable[goalIndex]:GetChartKey() + goalsong = SONGMAN:GetSongByChartKey(ck) + goalsteps = SONGMAN:GetStepsByChartKey(ck) + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowGoalDetailMessageCommand = function(self, params) + if params.index == i then + theDetail = true + self:diffusealpha(1) + else + if goaltable[goalIndex] ~= nil then + self:diffusealpha(0.5) + end + end + end, + HideGoalDetailMessageCommand = function(self) + theDetail = false + inDetail = false + if goaltable[goalIndex] ~= nil then + self:finishtweening() + self:easeOut(0.5) + self:diffusealpha(1) + else + self:playcommand("Hide") + end + end + } + + -- Tag index number + r[#r+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(-10,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + end, + SetCommand = function(self) + self:settextf("%d", goalIndex) + end + } + + -- The tag button + r[#r+1] = quadButton(6) .. { + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(boxWidth, boxHeight) + end, + TopPressedCommand = function(self, params) + if goaltable[goalIndex] ~= nil then + if params.input == "DeviceButton_left mouse button" then + if goaltable[goalIndex] and goalsong and goalsteps and ((inDetail and theDetail) or not inDetail) then + MESSAGEMAN:Broadcast("TriggerExitFromPS",{song = goalsong}) + GAMESTATE:GetSongOptionsObject("ModsLevel_Preferred"):MusicRate(goaltable[goalIndex]:GetRate()) + GAMESTATE:GetSongOptionsObject("ModsLevel_Song"):MusicRate(goaltable[goalIndex]:GetRate()) + GAMESTATE:GetSongOptionsObject("ModsLevel_Current"):MusicRate(goaltable[goalIndex]:GetRate()) + SCREENMAN:GetTopScreen():Cancel() + end + elseif params.input == "DeviceButton_right mouse button" then + if goaltable[goalIndex] and not inDetail then + inDetail = true + MESSAGEMAN:Broadcast("ShowGoalDetail", {index = i, goalIndex = goalIndex}) + end + end + end + end + } + + -- File name + r[#r+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(45,-5):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + if goalsong then + self:settextf("%s",goalsong:GetDisplayMainTitle()) + else + self:settextf("%s", ck) + end + self:maxwidth(boxWidth * 2) + end + } + + -- Goal percent + r[#r+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(10,5):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:maxwidth(boxWidth / 6) + end, + SetCommand = function(self) + if goaltable[goalIndex] then + local perc = math.floor(goaltable[goalIndex]:GetPercent() * 10000) / 100 + if perc < 99 then + self:settextf("%.f%%", perc) + else + self:settextf("%.2f%%", perc) + end + end + end, + UpdateGoalDetailsMessageCommand = function(self) + self:queuecommand("Set") + end + } + + -- Best percent + r[#r+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(45,5):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + local pb = goaltable[goalIndex]:GetPBUpTo() + if pb then + if pb:GetMusicRate() < goaltable[goalIndex]:GetRate() then + local ratestring = string.format("%.2f", pb:GetMusicRate()):gsub("%.?0$", "") .. "x" + self:settextf("Best: %5.2f%% (%s)", pb:GetWifeScore() * 100, ratestring) + else + self:settextf("Best: %5.2f%%", pb:GetWifeScore() * 100) + end + self:diffuse(getGradeColor(pb:GetWifeGrade())) + self:visible(true) + else + self:settextf("(Best: %5.2f%%)", 0) + self:diffuse(byAchieved(goaltable[goalIndex])) + end + end + } + + -- Assigned date + r[#r+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(boxWidth - 135,5):halign(0) + self:maxwidth(boxWidth / 2) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + self:settextf("Assigned: %s", goaltable[goalIndex]:WhenAssigned()) + self:diffuse(byAchieved(goaltable[goalIndex])) + end + } + + -- Achieved date + r[#r+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(boxWidth - 135,-5):halign(0) + self:maxwidth(boxWidth / 2) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + if goaltable[goalIndex]:IsAchieved() then + self:settextf("Achieved: %s", goaltable[goalIndex]:WhenAchieved()) + elseif goaltable[goalIndex]:IsVacuous() then + self:settext("Vacuous goal") + else + self:settext("") + end + self:diffuse(byAchieved(goaltable[goalIndex])) + end + } + + -- MSD + r[#r+1] = LoadFont("Common Bold")..{ + Name = "MSDString", + InitCommand = function(self) + self:xy(boxWidth - 25,0):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + if goalsteps and goaltable[goalIndex] then + local msd = goalsteps:GetMSD(goaltable[goalIndex]:GetRate(), 1) + self:settextf("%5.1f", msd) + self:diffuse(byMSD(msd)) + else + self:settext("??") + end + end, + UpdateGoalDetailsMessageCommand = function(self) + self:queuecommand("Set") + end + } + + -- Rate + r[#r+1] = LoadFont("Common Bold")..{ + Name = "RateString", + InitCommand = function(self) + self:xy(10,-5):halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + if goaltable[goalIndex] then + local ratestring = string.format("%.2f", goaltable[goalIndex]:GetRate()):gsub("%.?0$", "") .. "x" + self:settext(ratestring) + end + end, + UpdateGoalDetailsMessageCommand = function(self) + self:queuecommand("Set") + end + } + + -- Color for the button to show assign status + r[#r+1] = Def.Quad{ + Name = "Status", + InitCommand = function(self) + self:halign(0) + self:diffuse(color(colorConfig:get_data().main.highlight)) + self:diffusealpha(0.8) + self:xy(0, 0) + self:zoomto(4, boxHeight) + end, + SetCommand = function(self) + if goalsteps and goalsong then + local diff = goalsteps:GetDifficulty() + self:diffuse(byDifficulty(diff)) + else + self:diffuse(getMainColor("negative")) + end + end + } + + return r + end + + for i = 1, maxGoals do + t[#t+1] = goalItem(i) + end + + return t +end + +t[#t+1] = upperLeftContainer() + +t[#t+1] = lowerLeftContainer() + +t[#t+1] = rightContainer() + +t[#t+1] = LoadActor("../_cursor") + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenGoalManager underlay/default.lua b/BGAnimations/ScreenGoalManager underlay/default.lua new file mode 100644 index 00000000..c7a31b85 --- /dev/null +++ b/BGAnimations/ScreenGoalManager underlay/default.lua @@ -0,0 +1,10 @@ +local t = Def.ActorFrame{} + +t[#t+1] = Def.Quad { + InitCommand = function(self) + self:diffusealpha(0.8) + self:FullScreen() + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenGroupInfo overlay/default.lua b/BGAnimations/ScreenGroupInfo overlay/default.lua index cf3b6255..fd23b38b 100644 --- a/BGAnimations/ScreenGroupInfo overlay/default.lua +++ b/BGAnimations/ScreenGroupInfo overlay/default.lua @@ -78,27 +78,31 @@ local function topRow() InitCommand = function(self) self:zoomto(frameWidth, frameHeight) self:diffuse(color("#000000")):diffusealpha(0.8) - end; + end } - t[#t+1] = Def.Banner{ - Name = "Banner"; + t[#t+1] = Def.Sprite { + Name = "Banner", InitCommand = function(self) self:x(-frameWidth/2 + 5) self:halign(0) self:scaletoclipped(96, 30) - self:LoadFromSongGroup(group) - end; + local bnpath = SONGMAN:GetSongGroupBannerPath(group) + if not bnpath or bnpath == "" then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) + end } t[#t+1] = LoadFont("Common BLarge") .. { - Name = "SongTitle"; + Name = "SongTitle", InitCommand = function(self) self:xy(-frameWidth/2 + 96 +10, -2) self:zoom(0.3) self:halign(0) self:settext(group) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { @@ -107,10 +111,10 @@ local function topRow() self:zoom(0.35) self:halign(1) self:playcommand("Set") - end; + end, YieldMessageCommand = function(self, params) self:settextf("%d Songs / %d Steps", params.numSongs, params.numSteps) - end; + end } return t @@ -128,10 +132,10 @@ local function barGraphBars(i) self:y(-5) self:diffuse(getMSDColor(i)) self:valign(1) - end; + end, YieldMessageCommand = function(self) self:zoomto(10,MSDTable[i]/barCurMaxValue*barMaxHeight) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { @@ -139,7 +143,7 @@ local function barGraphBars(i) self:zoom(0.4) self:diffuse(color("#000000")) self:settextf("%d", MSDTable[i]) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { @@ -154,7 +158,7 @@ local function barGraphBars(i) else self:settextf("%d", i-1) end - end; + end } return t @@ -170,13 +174,14 @@ local t = Def.ActorFrame { top = SCREENMAN:GetTopScreen() top:AddInputCallback(input) co = coroutine.create(updateFromGroup) - end; + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end } t[#t+1] = topRow() .. { InitCommand = function(self) self:xy(SCREEN_CENTER_X, 50) - end; + end } for i=1, maxMSD+1 do @@ -188,20 +193,21 @@ end t[#t+1] = LoadActor("../_mouse") t[#t+1] = LoadActor("../_frame") - +--[[ local tab = TAB:new({"Difficulty Distribution"}) t[#t+1] = tab:makeTabActors() .. { OnCommand = function(self) self:y(SCREEN_HEIGHT+tab.height/2) self:easeOut(0.5) self:y(SCREEN_HEIGHT-tab.height/2) - end; + end, OffCommand = function(self) self:y(SCREEN_HEIGHT+tab.height/2) - end; + end, TabPressedMessageCommand = function(self, params) end } +]] t[#t+1] = LoadActor("../_cursor") diff --git a/BGAnimations/ScreenMapControllers underlay.lua b/BGAnimations/ScreenMapControllers underlay.lua index 9bc7376f..a44effd0 100644 --- a/BGAnimations/ScreenMapControllers underlay.lua +++ b/BGAnimations/ScreenMapControllers underlay.lua @@ -1,20 +1,20 @@ local t = Def.ActorFrame{} t[#t+1] = LoadActor("_background") -t[#t+1] = LoadActor("_particles"); +t[#t+1] = LoadActor("_particles") t[#t+1] = Def.Quad{ InitCommand = function(self) self:FullScreen() self:Center() self:diffuse(getMainColor("frame")):diffusealpha(0) - end; + end, OnCommand = function(self) self:smooth(0.5) self:diffusealpha(0.8) - end; + end, OffCommand = function(self) self:smooth(0.5) self:diffusealpha(0) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenMusicInfo overlay/default.lua b/BGAnimations/ScreenMusicInfo overlay/default.lua index c923e6f7..005b95c6 100644 --- a/BGAnimations/ScreenMusicInfo overlay/default.lua +++ b/BGAnimations/ScreenMusicInfo overlay/default.lua @@ -8,6 +8,9 @@ local maxItems = 10 local maxPages = math.ceil(#scoreList/maxItems) local curPage = 1 +local inDetail = false +local transitioning = false + local validStepsType = { 'StepsType_Dance_Single', 'StepsType_Dance_Solo', @@ -49,20 +52,32 @@ local function input(event) SCREENMAN:GetTopScreen():Cancel() end - if event.button == "EffectUp" then - changeMusicRate(0.05) + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") end - - if event.button == "EffectDown" then - changeMusicRate(-0.05) + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") end - if event.button == "MenuLeft" then + if event.button == "EffectUp" and not inDetail then + changeMusicRate(0.05) + elseif event.button == "EffectDown" and not inDetail then + changeMusicRate(-0.05) + elseif event.button == "MenuLeft" and not inDetail then movePage(-1) + elseif event.button == "MenuRight" and not inDetail then + movePage(1) end - if event.button == "MenuRight" then - movePage(1) + local numpad = event.DeviceInput.button == "DeviceButton_KP "..event.char + if not numpad and event.char and tonumber(event.char) and not transitioning then + if tonumber(event.char) == 1 then + SCREENMAN:AddNewScreenToTop("ScreenFileTagManager") + elseif tonumber(event.char) == 2 then + SCREENMAN:AddNewScreenToTop("ScreenChartPreview") + elseif tonumber(event.char) == 3 and DLMAN:IsLoggedIn() then + SCREENMAN:AddNewScreenToTop("ScreenChartLeaderboard") + end end end @@ -72,6 +87,7 @@ local function input(event) end local top +local replayScore local t = Def.ActorFrame { OnCommand = function(self) @@ -79,7 +95,17 @@ local t = Def.ActorFrame { MESSAGEMAN:Broadcast("SetSteps",{steps = steps}) top = SCREENMAN:GetTopScreen() top:AddInputCallback(input) - end; + end, + TriggerExitFromMIMessageCommand = function(self, params) + self:sleep(0.1) + replayScore = params.score + transitioning = true + self:queuecommand("DelayedExitMI") + end, + DelayedExitMICommand = function(self) + MESSAGEMAN:Broadcast("TriggerReplayBegin", {score = replayScore}) + SCREENMAN:GetTopScreen():Cancel() + end } @@ -94,21 +120,25 @@ local function topRow() InitCommand = function(self) self:zoomto(frameWidth, frameHeight) self:diffuse(color("#000000")):diffusealpha(0.8) - end; + end } - t[#t+1] = Def.Banner{ - Name = "Banner"; + t[#t+1] = Def.Sprite { + Name = "Banner", InitCommand = function(self) self:x(-frameWidth/2 + 5) self:halign(0) - self:LoadFromSong(song) + local bnpath = song:GetBannerPath() + if not bnpath then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) self:scaletoclipped(96, 30) end } t[#t+1] = LoadFont("Common BLarge") .. { - Name = "SongTitle"; + Name = "SongTitle", InitCommand = function(self) self:xy(-frameWidth/2 + 96 +10, -9) self:zoom(0.25) @@ -117,7 +147,7 @@ local function topRow() if #song:GetDisplaySubTitle() == 0 then self:zoom(0.35):y(-5) end - end; + end } t[#t+1] = LoadFont("Common Normal") .. { @@ -130,13 +160,13 @@ local function topRow() self:zoom(0.3) self:halign(0) self:playcommand("Set") - end; + end, SetCommand = function(self) local length = song:GetStepsSeconds()/getCurRateValue() self:settextf("%s",SecondsToMSS(length)) self:diffuse(getSongLengthColor(length)) - end; - CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end; + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end } @@ -146,7 +176,7 @@ local function topRow() self:zoom(0.35) self:halign(0) self:settext(song:GetDisplaySubTitle()) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { @@ -155,7 +185,7 @@ local function topRow() self:zoom(0.35) self:halign(0) self:settext("// "..song:GetDisplayArtist()) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { @@ -164,7 +194,7 @@ local function topRow() self:zoom(0.5) self:halign(1) self:playcommand("Set", {steps = steps}) - end; + end, SetCommand = function(self, params) local curSteps = params.steps local diff = curSteps:GetDifficulty() @@ -184,10 +214,10 @@ local function topRow() self:settext(ToEnumShortString(stype):gsub("%_"," ").." "..difftext.." "..meter) self:diffuse(getDifficultyColor(GetCustomDifficulty(stype,diff))) - end; + end, SetStepsMessageCommand = function(self, params) self:playcommand("Set",{steps = params.steps}) - end; + end } @@ -198,7 +228,7 @@ local function topRow() self:zoom(0.35) self:halign(1) self:playcommand("Set", {steps = steps}) - end; + end, SetCommand = function(self, params) local curSteps = params.steps local notes = 0 @@ -207,20 +237,20 @@ local function topRow() end self:settextf("%d Notes", notes) self:diffuse(Saturation(getDifficultyColor(GetCustomDifficulty(curSteps:GetStepsType(),curSteps:GetDifficulty())),0.3)) - end; + end, SetStepsMessageCommand = function(self, params) self:playcommand("Set",{steps = params.steps}) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ - Name="MSDAvailability"; + Name="MSDAvailability", InitCommand = function(self) self:xy(frameWidth/2-5,-11) self:zoom(0.30) self:halign(1) self:playcommand("Set", {steps = steps}) - end; + end, SetCommand = function(self, params) local curSteps = params.steps if curSteps ~= nil then @@ -234,11 +264,11 @@ local function topRow() self:diffuse(color(colorConfig:get_data().main.enabled)) end end - end; + end, SetStepsMessageCommand = function(self, params) self:playcommand("Set",{steps = params.steps}) - end; - }; + end + } t[#t+1] = LoadActor(THEME:GetPathG("", "round_star")) .. { InitCommand = function(self) @@ -250,7 +280,7 @@ local function topRow() if not song:IsFavorited() then self:visible(false) end - end; + end } return t @@ -270,7 +300,7 @@ local function stepsListRow() stepsTable = song:GetStepsByStepsType(params.st) table.sort(stepsTable, meterComparator) self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) - end; + end } t[#t+1] = Def.Quad{ @@ -279,7 +309,7 @@ local function stepsListRow() self:xy(-topRowFrameWidth/2, topRowFrameHeight) self:diffuse(color("#000000")):diffusealpha(0.8) self:halign(0) - end; + end } @@ -290,7 +320,7 @@ local function stepsListRow() self:diffuse(color("#FFFFFF")):diffusealpha(0) self:halign(0) self:faderight(0.5) - end; + end, TopPressedCommand = function(self, params) MESSAGEMAN:Broadcast("SetStepsType", {st = getNextStepsType(-1)}) self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") @@ -299,7 +329,7 @@ local function stepsListRow() self:diffusealpha(0.2) self:smooth(0.3) self:diffusealpha(0) - end; + end } t[#t+1] = quadButton(6)..{ InitCommand = function(self) @@ -308,7 +338,7 @@ local function stepsListRow() self:diffuse(color("#FFFFFF")):diffusealpha(0) self:halign(0) self:fadeleft(0.5) - end; + end, TopPressedCommand = function(self, params) MESSAGEMAN:Broadcast("SetStepsType", {st = getNextStepsType(1)}) self:GetParent():GetChild("TriangleRight"):playcommand("Tween") @@ -317,38 +347,38 @@ local function stepsListRow() self:diffusealpha(0.2) self:smooth(0.3) self:diffusealpha(0) - end; + end } t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { - Name = "TriangleLeft"; + Name = "TriangleLeft", InitCommand = function(self) self:zoom(0.15) self:diffusealpha(0.8) self:xy(-topRowFrameWidth/2+10,topRowFrameHeight) self:rotationz(-90) - end; + end, TweenCommand = function(self) self:finishtweening() self:diffuse(getMainColor('highlight')):diffusealpha(0.8) self:smooth(0.5) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) - end; + end } t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { - Name = "TriangleRight"; + Name = "TriangleRight", InitCommand = function(self) self:zoom(0.15) self:diffusealpha(0.8) self:xy(-topRowFrameWidth/2+frameWidth-10,topRowFrameHeight) self:rotationz(90) - end; + end, TweenCommand = function(self) self:finishtweening() self:diffuse(getMainColor('highlight')):diffusealpha(0.8) self:smooth(0.5) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) - end; + end } @@ -356,10 +386,10 @@ local function stepsListRow() InitCommand = function(self) self:zoom(0.4) self:xy(-topRowFrameWidth/2+frameWidth/2,topRowFrameHeight) - end; + end, SetCommand = function(self) self:settext(ToEnumShortString(stepsType):gsub("%_"," ")) - end; + end } for i = 1, maxNumDifficulties do @@ -372,7 +402,7 @@ local function stepsListRow() self:diffuse(color("#000000")):diffusealpha(0) self:halign(0) self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) - end; + end, SetCommand = function(self) local curSteps = stepsTable[i] if curSteps then @@ -380,7 +410,7 @@ local function stepsListRow() else self:playcommand("Hide") end - end; + end, ShowCommand = function(self) self:y(topRowFrameHeight) self:finishtweening() @@ -388,15 +418,15 @@ local function stepsListRow() self:easeOut(1) self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)) self:diffusealpha(0.8) - end; + end, HideCommand = function(self) self:diffusealpha(0) self:y(SCREEN_HEIGHT*10) self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) - end; + end, TopPressedCommand = function(self) MESSAGEMAN:Broadcast("SetSteps", {steps = stepsTable[i]}) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { @@ -406,7 +436,7 @@ local function stepsListRow() self:diffusealpha(0) self:xy((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10, topRowFrameHeight) self:settext("0") - end; + end, SetCommand = function(self) local curSteps = stepsTable[i] if curSteps then @@ -423,20 +453,20 @@ local function stepsListRow() else self:playcommand("Hide") end - end; + end, ShowCommand = function(self) self:finishtweening() self:sleep((i-1)*0.05) self:easeOut(1) self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)) self:diffusealpha(1) - end; + end, HideCommand = function(self) self:finishtweening() self:easeOut(1) self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10) self:diffusealpha(0) - end; + end } end @@ -457,7 +487,7 @@ local function stepsBPMRow() self:xy(topRowFrameWidth/2, topRowFrameHeight) self:diffuse(color("#000000")):diffusealpha(0.8) self:halign(1) - end; + end } t[#t+1] = quadButton(6)..{ @@ -467,7 +497,7 @@ local function stepsBPMRow() self:diffuse(color("#FFFFFF")):diffusealpha(0) self:halign(1) self:faderight(0.5) - end; + end, TopPressedCommand = function(self, params) changeMusicRate(-0.05) self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") @@ -476,7 +506,7 @@ local function stepsBPMRow() self:diffusealpha(0.2) self:smooth(0.3) self:diffusealpha(0) - end; + end } t[#t+1] = quadButton(6)..{ InitCommand = function(self) @@ -485,7 +515,7 @@ local function stepsBPMRow() self:diffuse(color("#FFFFFF")):diffusealpha(0) self:halign(1) self:fadeleft(0.5) - end; + end, TopPressedCommand = function(self, params) changeMusicRate(0.05) self:GetParent():GetChild("TriangleRight"):playcommand("Tween") @@ -494,47 +524,47 @@ local function stepsBPMRow() self:diffusealpha(0.2) self:smooth(0.3) self:diffusealpha(0) - end; + end } t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { - Name = "TriangleLeft"; + Name = "TriangleLeft", InitCommand = function(self) self:zoom(0.15) self:diffusealpha(0.8) self:xy(topRowFrameWidth/2-frameWidth+10,topRowFrameHeight) self:rotationz(-90) - end; + end, TweenCommand = function(self) self:finishtweening() self:diffuse(getMainColor('highlight')):diffusealpha(0.8) self:smooth(0.5) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) - end; + end } t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { - Name = "TriangleRight"; + Name = "TriangleRight", InitCommand = function(self) self:zoom(0.15) self:diffusealpha(0.8) self:xy(topRowFrameWidth/2-10,topRowFrameHeight) self:rotationz(90) - end; + end, TweenCommand = function(self) self:finishtweening() self:diffuse(getMainColor('highlight')):diffusealpha(0.8) self:smooth(0.5) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) - end; + end } t[#t+1] = LoadFont("Common Bold") .. { InitCommand = function(self) self:zoom(0.35) self:xy(topRowFrameWidth/2-75,topRowFrameHeight-4) - end; + end, SetStepsMessageCommand = function(self, params) if params.steps then local bpms = steps:GetTimingData():GetActualBPM() @@ -544,21 +574,40 @@ local function stepsBPMRow() self:settext(string.format("BPM: %d-%d (%d)",bpms[1]*getCurRateValue(),bpms[2]*getCurRateValue(),getCommonBPM(song:GetTimingData():GetBPMsAndTimes(true),song:GetLastBeat()))) end end - end; + end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand = function(self) self:zoom(0.3) self:xy(topRowFrameWidth/2-75,topRowFrameHeight+4) - end; + end, SetStepsMessageCommand = function(self, params) self:settext(getCurRateDisplayString()) - end; + end } return t end +local function offsetInput(event) + if event.type == "InputEventType_FirstPress" and inDetail then + local outputName = "" + if event.button == "EffectUp" then + outputName = "NextJudge" + elseif event.button == "EffectDown" then + outputName = "PrevJudge" + elseif event.button == "MenuDown" then + outputName = "ToggleHands" + elseif event.button == "MenuUp" then + outputName = "ResetJudge" + end + + if outputName ~= "" then + MESSAGEMAN:Broadcast("OffsetPlotModification", {Name = outputName}) + end + end +end + local function scoreList() local frameWidth = 430 local frameHeight = 340 @@ -585,6 +634,16 @@ local function scoreList() self:halign(0):valign(0) self:diffuse(getMainColor("frame")) self:diffusealpha(0.8) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() and SCREENMAN:GetTopScreen():GetName() == "ScreenMusicInfo" then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() and SCREENMAN:GetTopScreen():GetName() == "ScreenMusicInfo" then + movePage(1) + end end } @@ -595,17 +654,17 @@ local function scoreList() self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Scores") - end; + end } t[#t+1] = LoadFont("Common Normal")..{ - Name = "NoScore"; + Name = "NoScore", InitCommand = function(self) self:xy(frameWidth/2, frameHeight/2) self:zoom(0.4) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.6) self:settext("No scores here!\n(* ` ω´)") - end; + end, SetCommand = function(self) self:finishtweening() self:y(frameHeight/2-5) @@ -629,7 +688,7 @@ local function scoreList() InitCommand = function(self) self:diffusealpha(0) self:xy(scoreItemX, scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)-10) - end; + end, ShowCommand = function(self) self:y(scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)-10) self:diffusealpha(0) @@ -638,13 +697,13 @@ local function scoreList() self:easeOut(1) self:y(scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)) self:diffusealpha(1) - end; + end, HideCommand = function(self) self:stoptweening() self:easeOut(0.5) self:diffusealpha(0) self:y(SCREEN_HEIGHT*10) -- Throw it offscreen - end; + end, UpdateListMessageCommand = function(self) detail = false scoreIndex = (curPage-1)*10+i @@ -654,7 +713,7 @@ local function scoreList() else self:playcommand("Hide") end - end; + end, ShowScoreDetailMessageCommand = function(self, params) if params.index == i then detail = true @@ -665,13 +724,13 @@ local function scoreList() else self:playcommand("Hide") end - end; + end, HideScoreDetailMessageCommand = function(self) detail = false if scoreList ~= nil and scoreList[scoreIndex] ~= nil then self:playcommand("Show") end - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -679,10 +738,10 @@ local function scoreList() self:xy(-10,0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) - end; + end, SetCommand = function(self) self:settextf("%d", scoreIndex) - end; + end } t[#t+1] = quadButton(6) .. { @@ -690,7 +749,7 @@ local function scoreList() self:halign(0) self:diffusealpha(0.2) self:zoomto(scoreItemWidth, scoreItemHeight) - end; + end, TopPressedCommand = function(self, params) self:finishtweening() self:diffusealpha(0.4) @@ -703,7 +762,7 @@ local function scoreList() elseif params.input == "DeviceButton_right mouse button" then MESSAGEMAN:Broadcast("HideScoreDetail") end - end; + end, SetCommand = function(self) if scoreList[i]:GetEtternaValid() then self:diffuse(color("#FFFFFF")) @@ -711,17 +770,17 @@ local function scoreList() self:diffuse(color(colorConfig:get_data().clearType.ClearType_Invalid)) end self:diffusealpha(0.2) - end; + end } t[#t+1] = getClearTypeLampQuad(3, scoreItemHeight)..{ InitCommand = function(self) self:halign(0) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) self:playcommand("SetClearType", {clearType = getClearType(pn,steps,scoreList[scoreIndex])}) - end; + end } @@ -730,12 +789,12 @@ local function scoreList() self:xy(20,0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) - end; + end, SetCommand = function(self) local ssr = scoreList[scoreIndex]:GetSkillsetSSR("Overall") self:settextf("%0.2f",ssr) self:diffuse(getMSDColor(ssr)) - end; + end } t[#t+1] = LoadFont("Common Bold")..{ @@ -744,7 +803,7 @@ local function scoreList() self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) self:halign(0) - end; + end, SetCommand = function(self) local clearType = getClearType(pn,steps,scoreList[scoreIndex]) @@ -754,13 +813,13 @@ local function scoreList() } t[#t+1] = LoadFont("Common Bold")..{ - Name = "Grade"; + Name = "Grade", InitCommand = function(self) self:xy(40,5) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) self:halign(0) - end; + end, SetCommand = function(self) local grade = scoreList[scoreIndex]:GetWifeGrade() self:settext(THEME:GetString("Grade",ToEnumShortString(grade))) @@ -769,13 +828,13 @@ local function scoreList() } t[#t+1] = LoadFont("Common Normal")..{ - Name = "PercentScore"; + Name = "PercentScore", InitCommand = function(self) self:xy(40,5) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) self:halign(0) - end; + end, SetCommand = function(self) local score = scoreList[scoreIndex]:GetWifeScore() local w1 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W1") @@ -790,13 +849,13 @@ local function scoreList() } t[#t+1] = LoadFont("Common Normal")..{ - Name = "ReplayAvailability"; + Name = "ReplayAvailability", InitCommand = function(self) self:xy(scoreItemWidth-5,5) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) self:halign(1) - end; + end, SetCommand = function(self) if scoreList[scoreIndex]:HasReplayData() then self:settext("Replay Data Available.") @@ -808,47 +867,160 @@ local function scoreList() end } + t[#t+1] = LoadFont("Common Normal") .. { + Name = "Date", + InitCommand = function(self) + self:xy(scoreItemWidth-5,-5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(1) + end, + SetCommand = function(self) + self:settext(scoreList[scoreIndex]:GetDate()) + end + } + return t end local function scoreDetail() + local scoreIndex local t = Def.ActorFrame{ InitCommand = function(self) self:diffusealpha(0) self:xy(scoreItemX, scoreItemY+scoreItemYSpacing+scoreItemHeight/2) - end; + end, HideCommand = function(self) self:stoptweening() self:easeOut(0.5) self:diffusealpha(0) - end; + end, ShowScoreDetailMessageCommand = function(self, params) + scoreIndex = params.scoreIndex + inDetail = true self:finishtweening() self:xy(scoreItemX, (params.index+1)*(scoreItemHeight+scoreItemYSpacing)+100+scoreItemHeight/2) self:easeOut(0.5) self:xy(scoreItemX, scoreItemY+scoreItemYSpacing+scoreItemHeight/2) self:diffusealpha(1) - end; + end, HideScoreDetailMessageCommand = function(self) + inDetail = false self:playcommand("Hide") - end; + end, UpdateListMessageCommand = function(self) + inDetail = false self:playcommand("Hide") end } + -- Watch online replay button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowScoreDetailMessageCommand = function(self, params) + if scoreList[params.scoreIndex]:HasReplayData() then + self:diffusealpha(0.8) + else + self:diffusealpha(0.2) + end + end, + + TopPressedCommand = function(self) + if scoreList[scoreIndex]:HasReplayData() then + self:finishtweening() + self:diffusealpha(1) + self:smooth(0.3) + self:diffusealpha(0.8) + MESSAGEMAN:Broadcast("TriggerReplayBegin", {score = scoreList[scoreIndex]}) + SCREENMAN:GetTopScreen():Cancel() + end + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:diffusealpha(0.4) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("Watch") + end, + ShowScoreDetailMessageCommand = function(self, params) + if scoreList[params.scoreIndex]:HasReplayData() then + self:diffusealpha(1) + else + self:diffusealpha(0.4) + end + end, + } + + -- View eval screen for score button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3 + 95,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowScoreDetailMessageCommand = function(self, params) + if scoreList[params.scoreIndex]:HasReplayData() then + self:diffusealpha(0.8) + else + self:diffusealpha(0.2) + end + end, + + TopPressedCommand = function(self) + if scoreList[scoreIndex]:HasReplayData() then + self:finishtweening() + self:diffusealpha(1) + self:smooth(0.3) + self:diffusealpha(0.8) + MESSAGEMAN:Broadcast("TriggerReplayBegin", {score = scoreList[scoreIndex], isEval = true}) + SCREENMAN:GetTopScreen():Cancel() + end + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3 + 95,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:diffusealpha(0.4) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("View Eval") + end, + ShowScoreDetailMessageCommand = function(self, params) + if scoreList[params.scoreIndex]:HasReplayData() then + self:diffusealpha(1) + else + self:diffusealpha(0.4) + end + end, + } + t[#t+1] = Def.Quad{ InitCommand = function(self) self:diffusealpha(0.2) self:halign(0):valign(0) self:zoomto(scoreItemWidth, frameHeight-80) - end; + end, } t[#t+1] = LoadActor(THEME:GetPathG("","OffsetGraph"))..{ InitCommand = function(self, params) self:xy(5, 55) - end; + end, + OnCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(offsetInput) + end, ShowScoreDetailMessageCommand = function(self, params) if scoreList[params.scoreIndex]:HasReplayData() then @@ -857,14 +1029,17 @@ local function scoreList() height = frameHeight-140, song = song, steps = steps, - noterow = scoreList[params.scoreIndex]:GetNoteRowVector(), - offset = scoreList[params.scoreIndex]:GetOffsetVector()} + nrv = scoreList[params.scoreIndex]:GetNoteRowVector(), + dvt = scoreList[params.scoreIndex]:GetOffsetVector(), + ctt = scoreList[params.scoreIndex]:GetTrackVector(), + ntt = scoreList[params.scoreIndex]:GetTapNoteTypeVector(), + columns = steps:GetNumColumns()} self:playcommand("Update", params) end ) else self:RunCommandsOnChildren(function(self) self:playcommand("Update", {width = scoreItemWidth-10, height = frameHeight-140,}) end) end - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -874,10 +1049,10 @@ local function scoreList() self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.6) self:settext("No replay data\n(゜´Д`゜)") - end; + end, ShowScoreDetailMessageCommand = function(self, params) self:visible(not scoreList[params.scoreIndex]:HasReplayData()) - end; + end } return t @@ -898,49 +1073,49 @@ end t[#t+1] = Def.Actor{ SetStepsMessageCommand = function(self, params) steps = params.steps - end; + end, CurrentRateChangedMessageCommand = function(self) MESSAGEMAN:Broadcast("SetSteps",{steps = steps}) - end; + end } t[#t+1] = topRow() .. { InitCommand = function(self) self:xy(SCREEN_CENTER_X, 50) self:delayedFadeIn(0) - end; + end } t[#t+1] = stepsListRow() .. { InitCommand = function(self) self:xy(SCREEN_CENTER_X, 50) self:delayedFadeIn(1) - end; + end } t[#t+1] = stepsBPMRow() .. { InitCommand = function(self) self:xy(SCREEN_CENTER_X, 50) self:delayedFadeIn(2) - end; + end } t[#t+1] = LoadActor("stepsinfo") .. { InitCommand = function(self) self:xy(capWideScale(135,160),140) self:delayedFadeIn(3) - end; + end } t[#t+1] = LoadActor("ssrbreakdown") .. { InitCommand = function(self) self:xy(capWideScale(135,160),315) self:delayedFadeIn(4) - end; + end } t[#t+1] = scoreList() .. { - Name = "ScoreList"; + Name = "ScoreList", InitCommand = function(self) self:xy(320,110) self:delayedFadeIn(5) @@ -955,17 +1130,24 @@ t[#t+1] = LoadActor("../_mouse") t[#t+1] = LoadActor("../_frame") -local tab = TAB:new({"Scores", "Simfile Info", "Graphs"}) +local tab = TAB:new({"Manage Tags", "Preview", "Leaderboard", "", ""}) t[#t+1] = tab:makeTabActors() .. { OnCommand = function(self) self:y(SCREEN_HEIGHT+tab.height/2) self:easeOut(0.5) self:y(SCREEN_HEIGHT-tab.height/2) - end; + end, OffCommand = function(self) self:y(SCREEN_HEIGHT+tab.height/2) - end; + end, TabPressedMessageCommand = function(self, params) + if params.name == "Manage Tags" then + SCREENMAN:AddNewScreenToTop("ScreenFileTagManager") + elseif params.name == "Preview" then + SCREENMAN:AddNewScreenToTop("ScreenChartPreview") + elseif params.name == "Leaderboard" and DLMAN:IsLoggedIn() then + SCREENMAN:AddNewScreenToTop("ScreenChartLeaderboard") + end end } diff --git a/BGAnimations/ScreenMusicInfo overlay/ssrbreakdown.lua b/BGAnimations/ScreenMusicInfo overlay/ssrbreakdown.lua index a49d676b..41b285f8 100644 --- a/BGAnimations/ScreenMusicInfo overlay/ssrbreakdown.lua +++ b/BGAnimations/ScreenMusicInfo overlay/ssrbreakdown.lua @@ -38,7 +38,7 @@ t[#t+1] = LoadFont("Common Bold")..{ self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("MSD Breakdown") - end; + end } local sepAngle = 360/#SkillSets-1 @@ -52,18 +52,18 @@ local function makeMSDPoints(i) self:xy(x,y) self:zoom(0.3) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - end; + end, SetStepsMessageCommand = function(self, params) local steps = params.steps local MSD = steps:GetMSD(getCurRateValue(), i+1) self:settextf("%s\n%0.2f",SkillSets[i], MSD) self:AddAttribute(#SkillSets[i], {Length = -1, Diffuse = getMSDColor(MSD)}) - end; + end } end t[#t+1] = Def.ActorMultiVertex{ - Name= "SSR_MAX_Graph"; + Name= "SSR_MAX_Graph", InitCommand = function(self) local x,y for i=1, #SkillSets do @@ -79,27 +79,27 @@ t[#t+1] = Def.ActorMultiVertex{ self:SetDrawState{First= 1, Num= -1} self:SetDrawState{Mode="DrawMode_QuadStrip"} self:playcommand("Set") - end; + end, SetCommand = function(self) self:diffusealpha(0.2) self:SetVertices(maxVerts) self:SetDrawState{First= 1, Num= -1} - end; + end } t[#t+1] = Def.ActorMultiVertex{ - Name= "SSR_Graph"; + Name= "SSR_Graph", InitCommand = function(self) self:SetDrawState{Mode="DrawMode_QuadStrip"} self:queuecommand("Set") self:diffusealpha(0.5) - end; + end, SetCommand = function(self) self:finishtweening() self:easeOut(1) self:SetVertices(verts) self:SetDrawState{First= 1, Num= -1} - end; + end, SetStepsMessageCommand = function(self, params) verts = {} local steps = params.steps @@ -118,7 +118,7 @@ t[#t+1] = Def.ActorMultiVertex{ verts[#verts+1] = {{0,0,0},color("#FFFFFF")} self:playcommand("Set") - end; + end } for i=1, #SkillSets do @@ -132,13 +132,13 @@ t[#t+1] = LoadFont("Common Normal")..{ self:halign(1) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Overall:") - end; + end, SetStepsMessageCommand = function(self, params) local steps = params.steps local MSD = steps:GetMSD(getCurRateValue(), 1) self:settextf("Overall: %0.2f", MSD) self:AddAttribute(8, {Length = -1, Diffuse = getMSDColor(MSD)}) - end; + end } diff --git a/BGAnimations/ScreenMusicInfo overlay/stepsinfo.lua b/BGAnimations/ScreenMusicInfo overlay/stepsinfo.lua index 7f1a6ba8..941ee166 100644 --- a/BGAnimations/ScreenMusicInfo overlay/stepsinfo.lua +++ b/BGAnimations/ScreenMusicInfo overlay/stepsinfo.lua @@ -22,19 +22,22 @@ t[#t+1] = LoadFont("Common Normal")..{ self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) self:settextf("ChartKey: %s","") - end; + end, SetStepsMessageCommand = function(self, params) self:settextf("ChartKey: %s",params.steps:GetChartKey()) - end; + end } local parameters = { {"Notes","RadarCategory_Notes"}, + {"Jumps","RadarCategory_Jumps"}, + {"Hands","RadarCategory_Hands"}, {"Holds","RadarCategory_Holds"}, {"Rolls","RadarCategory_Rolls"}, {"Mines","RadarCategory_Mines"}, {"Lifts","RadarCategory_Lifts"}, + {"Fakes","RadarCategory_Fakes"} } for i,v in ipairs(parameters) do @@ -44,7 +47,7 @@ for i,v in ipairs(parameters) do self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) self:settext(v[1]) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -52,14 +55,14 @@ for i,v in ipairs(parameters) do self:xy((-frameWidth/2)+frameWidth/(#parameters+1)*i,3) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) - end; + end, SetStepsMessageCommand = function(self, params) self:settext(params.steps:GetRadarValues(pn):GetValue(v[2])) self:finishtweening() self:diffusealpha(0):y(0) self:easeOut(1) self:diffusealpha(1):y(3) - end; + end } end diff --git a/BGAnimations/ScreenNetChartLeaderboard decorations/default.lua b/BGAnimations/ScreenNetChartLeaderboard decorations/default.lua new file mode 100644 index 00000000..a8235dec --- /dev/null +++ b/BGAnimations/ScreenNetChartLeaderboard decorations/default.lua @@ -0,0 +1,3 @@ +local t = Def.ActorFrame{} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenPlaylistInfo out.lua b/BGAnimations/ScreenNetChartLeaderboard out.lua similarity index 100% rename from BGAnimations/ScreenPlaylistInfo out.lua rename to BGAnimations/ScreenNetChartLeaderboard out.lua diff --git a/BGAnimations/ScreenNetChartLeaderboard overlay/default.lua b/BGAnimations/ScreenNetChartLeaderboard overlay/default.lua new file mode 100644 index 00000000..ef492a7f --- /dev/null +++ b/BGAnimations/ScreenNetChartLeaderboard overlay/default.lua @@ -0,0 +1,1343 @@ +local pn = GAMESTATE:GetEnabledPlayers()[1] +local song = GAMESTATE:GetCurrentSong() +local steps = GAMESTATE:GetCurrentSteps(pn) +local stepsType = steps:GetStepsType() + +local scoreList = {} +local maxItems = 10 +local maxPages = math.ceil(#scoreList/maxItems) +local curPage = 1 +local currentCountry = "Global" + +local lbActor +local cheatIndex +local inDetail = false + +local validStepsType = { + 'StepsType_Dance_Single', + 'StepsType_Dance_Solo', + 'StepsType_Dance_Double', +} +local maxNumDifficulties = 0 +for _,st in pairs(validStepsType) do + maxNumDifficulties = math.max(maxNumDifficulties, #song:GetStepsByStepsType(st)) +end + +local filts = {"All Rates", "Current Rate"} +local topfilts = {"Top Scores", "All Scores"} + +local function getNextStepsType(n) + for i = 1, #validStepsType do + if validStepsType[i] == stepsType then + stepsType = validStepsType[(i+n-1+#validStepsType)%#validStepsType+1] -- 1 index scks + return stepsType + end + end +end + +local function movePage(n) + if n > 0 then + curPage = ((curPage+n-1) % maxPages + 1) + else + curPage = ((curPage+n+maxPages-1) % maxPages+1) + end + MESSAGEMAN:Broadcast("UpdateCLBList") +end + +local function meterComparator(stepA, stepB) + local diffA = stepA:GetDifficulty() + local diffB = stepB:GetDifficulty() + + return Enum.Reverse(Difficulty)[diffA] < Enum.Reverse(Difficulty)[diffB] +end + +local function updateLeaderBoardForCurrentChart() + if steps then + DLMAN:RequestChartLeaderBoardFromOnline( + steps:GetChartKey(), + function(leaderboard) + lbActor:queuecommand("SetFromLeaderboard", leaderboard) + end + ) + else + lbActor:queuecommand("SetFromLeaderboard", {}) + end +end + + +local function input(event) + + if event.type == "InputEventType_FirstPress" then + if event.button == "Back" or event.button == "Start" then + SCREENMAN:GetTopScreen():Cancel() + end + + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + end + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + end + + if event.button == "EffectUp" and not inDetail then + changeMusicRate(0.05) + elseif event.button == "EffectDown" and not inDetail then + changeMusicRate(-0.05) + elseif event.button == "MenuLeft" and not inDetail then + movePage(-1) + elseif event.button == "MenuRight" and not inDetail then + movePage(1) + end + end + return false + +end + +local top +local frameWidth = 430 +local frameHeight = 340 + +local verticalSpacing = 7 +local horizontalSpacing = 10 + +local function topRow() + local frameWidth = SCREEN_WIDTH - 20 + local frameHeight = 40 + + local t = Def.ActorFrame { + BeginCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + end + } + + t[#t+1] = Def.Sprite { + Name = "Banner", + InitCommand = function(self) + self:x(-frameWidth/2 + 5) + self:halign(0) + local bnpath = song:GetBannerPath() + if not bnpath then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) + self:scaletoclipped(96, 30) + end + } + + t[#t+1] = LoadFont("Common BLarge") .. { + Name = "SongTitle", + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, -9) + self:zoom(0.25) + self:halign(0) + self:settext(song:GetMainTitle()) + if #song:GetDisplaySubTitle() == 0 then + self:zoom(0.35):y(-5) + end + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + local actor = self:GetParent():GetChild("SongTitle") + local x = actor:GetX() + actor:GetWidth()*actor:GetZoomX() + 2 + local y = actor:GetY() - 2 + + self:xy(x,y) + self:zoom(0.3) + self:halign(0) + self:playcommand("Set") + end, + SetCommand = function(self) + local length = song:GetStepsSeconds()/getCurRateValue() + self:settextf("%s",SecondsToMSS(length)) + self:diffuse(getSongLengthColor(length)) + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 1) + self:zoom(0.35) + self:halign(0) + self:settext(song:GetDisplaySubTitle()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 9) + self:zoom(0.35) + self:halign(0) + self:settext("// "..song:GetDisplayArtist()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,-1) + self:zoom(0.5) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local diff = curSteps:GetDifficulty() + local stype = curSteps:GetStepsType() + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + meter = curSteps:GetMeter() + end + + local difftext + if diff == 'Difficulty_Edit' then + difftext = curSteps:GetDescription() + difftext = difftext == '' and getDifficulty(diff) or difftext + else + difftext = getDifficulty(diff) + end + + self:settext(ToEnumShortString(stype):gsub("%_"," ").." "..difftext.." "..meter) + self:diffuse(getDifficultyColor(GetCustomDifficulty(stype,diff))) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,9) + self:zoom(0.35) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local notes = 0 + if curSteps ~= nil then + notes = curSteps:GetRadarValues(pn):GetValue("RadarCategory_Notes") + end + self:settextf("%d Notes", notes) + self:diffuse(Saturation(getDifficultyColor(GetCustomDifficulty(curSteps:GetStepsType(),curSteps:GetDifficulty())),0.3)) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name="MSDAvailability", + InitCommand = function(self) + self:xy(frameWidth/2-5,-11) + self:zoom(0.30) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + if curSteps ~= nil then + + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + self:settext("Default") + self:diffuse(color(colorConfig:get_data().main.disabled)) + else + self:settext("MSD") + self:diffuse(color(colorConfig:get_data().main.enabled)) + end + end + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "round_star")) .. { + InitCommand = function(self) + self:xy(-frameWidth/2+1,-frameHeight/2+1) + self:zoom(0.3) + self:wag() + self:diffuse(Color.Yellow) + + if not song:IsFavorited() then + self:visible(false) + end + end + } + + return t +end + +local function stepsListRow() + local frameWidth = 150 + local frameHeight = 25 + local topRowFrameWidth = SCREEN_WIDTH - 20 + local topRowFrameHeight = 40 + + + local stepsTable = {} + local t = Def.ActorFrame{ + SetStepsTypeMessageCommand = function(self, params) + stepsTable = song:GetStepsByStepsType(params.st) + table.sort(stepsTable, meterComparator) + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:xy(-topRowFrameWidth/2, topRowFrameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(0) + end + + } + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(-topRowFrameWidth/2, topRowFrameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(0) + self:faderight(0.5) + end, + TopPressedCommand = function(self, params) + MESSAGEMAN:Broadcast("SetStepsType", {st = getNextStepsType(-1)}) + self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(-topRowFrameWidth/2+frameWidth/2, topRowFrameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(0) + self:fadeleft(0.5) + end, + TopPressedCommand = function(self, params) + MESSAGEMAN:Broadcast("SetStepsType", {st = getNextStepsType(1)}) + self:GetParent():GetChild("TriangleRight"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleLeft", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(-topRowFrameWidth/2+10,topRowFrameHeight) + self:rotationz(-90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleRight", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(-topRowFrameWidth/2+frameWidth-10,topRowFrameHeight) + self:rotationz(90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:zoom(0.4) + self:xy(-topRowFrameWidth/2+frameWidth/2,topRowFrameHeight) + end, + SetCommand = function(self) + self:settext(ToEnumShortString(stepsType):gsub("%_"," ")) + end + } + + for i = 1, maxNumDifficulties do + + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(40, frameHeight) + self:y(topRowFrameHeight) + self:diffuse(color("#000000")):diffusealpha(0) + self:halign(0) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) + end, + SetCommand = function(self) + local curSteps = stepsTable[i] + if curSteps then + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowCommand = function(self) + self:y(topRowFrameHeight) + self:finishtweening() + self:sleep((i-1)*0.03) + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)) + self:diffusealpha(0.8) + end, + HideCommand = function(self) + self:diffusealpha(0) + self:y(SCREEN_HEIGHT*10) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) + end, + TopPressedCommand = function(self) + MESSAGEMAN:Broadcast("SetSteps", {steps = stepsTable[i]}) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + local stype = steps:GetStepsType() + self:zoom(0.4) + self:diffusealpha(0) + self:xy((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10, topRowFrameHeight) + self:settext("0") + end, + SetCommand = function(self) + local curSteps = stepsTable[i] + if curSteps then + + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + meter = curSteps:GetMeter() + end + + self:settext(meter) + self:diffuse(color(colorConfig:get_data().difficulty[curSteps:GetDifficulty()])) + self:diffusealpha(0) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowCommand = function(self) + self:finishtweening() + self:sleep((i-1)*0.05) + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:finishtweening() + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10) + self:diffusealpha(0) + end + } + end + + return t +end + +local function stepsBPMRow() + local topRowFrameWidth = 0 + local topRowFrameHeight = 40 + local frameWidth = 150 + local frameHeight = 25 + local t = Def.ActorFrame{} + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, 25) + self:xy(topRowFrameWidth, topRowFrameHeight + frameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(1) + end + } + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(topRowFrameWidth/2-frameWidth/2, topRowFrameHeight + frameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:faderight(0.5) + end, + TopPressedCommand = function(self, params) + changeMusicRate(-0.05) + self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(topRowFrameWidth/2, topRowFrameHeight + frameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:fadeleft(0.5) + end, + TopPressedCommand = function(self, params) + changeMusicRate(0.05) + self:GetParent():GetChild("TriangleRight"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleLeft", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(topRowFrameWidth/2-frameWidth+10,topRowFrameHeight + frameHeight) + self:rotationz(-90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleRight", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(topRowFrameWidth/2-10,topRowFrameHeight + frameHeight) + self:rotationz(90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:zoom(0.35) + self:xy(topRowFrameWidth/2-75,topRowFrameHeight-4 + frameHeight) + end, + SetStepsMessageCommand = function(self, params) + if params.steps then + local bpms = steps:GetTimingData():GetActualBPM() + if bpms[1] == bpms[2] and bpms[1]~= nil then + self:settext(string.format("BPM: %d",bpms[1]*getCurRateValue())) + else + self:settext(string.format("BPM: %d-%d (%d)",bpms[1]*getCurRateValue(),bpms[2]*getCurRateValue(),getCommonBPM(song:GetTimingData():GetBPMsAndTimes(true),song:GetLastBeat()))) + end + end + end + } + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:zoom(0.3) + self:xy(topRowFrameWidth/2-75,topRowFrameHeight+4 + frameHeight) + end, + SetStepsMessageCommand = function(self, params) + self:settext(getCurRateDisplayString()) + end + } + + return t +end + + +local function offsetInput(event) + if event.type == "InputEventType_FirstPress" and inDetail then + local outputName = "" + if event.button == "EffectUp" then + outputName = "NextJudge" + elseif event.button == "EffectDown" then + outputName = "PrevJudge" + elseif event.button == "MenuDown" then + outputName = "ToggleHands" + elseif event.button == "MenuUp" then + outputName = "ResetJudge" + end + + if outputName ~= "" then + MESSAGEMAN:Broadcast("OffsetPlotModification", {Name = outputName}) + end + end +end + + +local function scoreList() + local frameWidth = 430 + local frameHeight = 340 + local t = Def.ActorFrame{ + SetStepsMessageCommand = function(self, params) + steps = params.steps + scoreList = DLMAN:GetChartLeaderBoard(steps:GetChartKey(), currentCountry) + if #scoreList == 0 then + updateLeaderBoardForCurrentChart() + end + curPage = 1 + if scoreList ~= nil then + maxPages = math.ceil(#scoreList/maxItems) + MESSAGEMAN:Broadcast("UpdateCLBList") + self:GetChild("NoScore"):visible(false) + else + maxPages = 1 + self:RunCommandsOnChildren(function(self) self:playcommand("Hide") end) + self:GetChild("NoScore"):visible(true):playcommand("Set") + end + end, + SetFromLeaderboardCommand = function(self, leaderboard) + scoreList = DLMAN:GetChartLeaderBoard(steps:GetChartKey(), currentCountry) + curPage = 1 + if scoreList ~= nil then + maxPages = math.ceil(#scoreList/maxItems) + MESSAGEMAN:Broadcast("UpdateCLBList") + self:GetChild("NoScore"):visible(false) + else + maxPages = 1 + self:RunCommandsOnChildren(function(self) self:playcommand("Hide") end) + self:GetChild("NoScore"):visible(true):playcommand("Set") + end + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name = "NoScore", + InitCommand = function(self) + self:xy(frameWidth/2, frameHeight/2) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.6) + self:settext("No scores here!\n(* ` ω´)") + end, + SetCommand = function(self) + self:finishtweening() + self:y(frameHeight/2-5) + self:easeOut(0.5) + self:y(frameHeight/2) + end + } + + local scoreItemWidth = frameWidth-30 + local scoreItemHeight = 25 + + local scoreItemX = 20 + local scoreItemY = 30+scoreItemHeight/2 + local scoreItemYSpacing = 5 + + local function scoreListItem(i) + local scoreIndex = (curPage-1)*10+i + local detail = false + local hs + + local t = Def.ActorFrame{ + InitCommand = function(self) + self:diffusealpha(0) + self:xy(scoreItemX, scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)-10) + end, + ShowCommand = function(self) + self:y(scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)-10) + self:diffusealpha(0) + self:finishtweening() + self:sleep((i-1)*0.03) + self:easeOut(1) + self:y(scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + self:y(SCREEN_HEIGHT*10) -- Throw it offscreen + end, + UpdateCLBListMessageCommand = function(self) + detail = false + scoreIndex = (curPage-1)*10+i + hs = scoreList[scoreIndex] + + if scoreList ~= nil and scoreList[scoreIndex] ~= nil then + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + if params.index == i then + detail = true + self:finishtweening() + self:easeOut(0.5) + self:y(scoreItemY) + self:valign(0) + else + self:playcommand("Hide") + end + end, + HideOnlineScoreDetailMessageCommand = function(self) + detail = false + if scoreList ~= nil and scoreList[scoreIndex] ~= nil then + self:playcommand("Show") + end + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(-10,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + end, + SetCommand = function(self) + self:settextf("%d", scoreIndex) + end + } + + t[#t+1] = quadButton(6) .. { + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(scoreItemWidth, scoreItemHeight) + end, + TopPressedCommand = function(self, params) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + if params.input == "DeviceButton_left mouse button" then + if not detail then + MESSAGEMAN:Broadcast("ShowOnlineScoreDetail", {index = i, scoreIndex = scoreIndex}) + end + elseif params.input == "DeviceButton_right mouse button" then + MESSAGEMAN:Broadcast("HideOnlineScoreDetail") + end + end, + SetCommand = function(self) + if scoreList[i]:GetEtternaValid() then + self:diffuse(color("#FFFFFF")) + else + self:diffuse(color(colorConfig:get_data().clearType.ClearType_Invalid)) + end + self:diffusealpha(0.2) + end + } + + t[#t+1] = getClearTypeLampQuad(3, scoreItemHeight)..{ + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.8) + end, + SetCommand = function(self) + self:playcommand("SetClearType", {clearType = getClearType(pn,steps,scoreList[scoreIndex])}) + end + } + + + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(20,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + local ssr = scoreList[scoreIndex]:GetSkillsetSSR("Overall") + self:settextf("%0.2f",ssr) + self:diffuse(getMSDColor(ssr)) + end + } + + t[#t+1] = LoadFont("Common Bold")..{ + Name = "DisplayName", + InitCommand = function(self) + self:xy(40,-6) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:halign(0) + end, + SetCommand = function(self) + if hs:GetChordCohesion() then + self:diffuse(color("#F0EEA6")) + else + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + end + self:settext(hs:GetDisplayName()) + end + + } + + t[#t+1] = LoadFont("Common Normal") .. { + Name = "RateString", + InitCommand = function(self) + self:xy(40,-6) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(0) + end, + SetCommand = function(self) + local ratestring = "("..string.format("%.2f", scoreList[scoreIndex]:GetMusicRate()):gsub("%.?0$", "") .. "x)" + self:settext(ratestring) + self:x(self:GetParent():GetChild("DisplayName"):GetX()+(self:GetParent():GetChild("DisplayName"):GetWidth()*0.4)+5) + end + } + t[#t+1] = LoadFont("Common Normal") .. { + Name = "CCON", + InitCommand = function(self) + self:xy(40,-6) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(0) + self:settext("(CC On)") + end, + SetCommand = function(self) + if hs:GetChordCohesion() then + self:visible(true) + else + self:visible(false) + end + local ratewidth = self:GetParent():GetChild("RateString"):GetX()+(self:GetParent():GetChild("RateString"):GetWidth()*0.4) + self:x(ratewidth) + end + } + + t[#t+1] = LoadFont("Common Bold")..{ + Name = "Grade", + InitCommand = function(self) + self:xy(40,5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:halign(0) + end, + SetCommand = function(self) + local grade = scoreList[scoreIndex]:GetWifeGrade() + self:settext(THEME:GetString("Grade",ToEnumShortString(grade))) + self:diffuse(getGradeColor(grade)) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name = "PercentScore", + InitCommand = function(self) + self:xy(40,5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(0) + end, + SetCommand = function(self) + local score = scoreList[scoreIndex]:GetWifeScore() + score = math.floor(score*1000000)/10000 + local w1 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W1") + local w2 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W2") + local w3 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W3") + local w4 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W4") + local w5 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W5") + local miss = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_Miss") + if score >= 99.5 then + self:settextf("%0.4f%% - %d / %d / %d / %d / %d / %d",score, w1, w2, w3, w4, w5, miss) + else + self:settextf("%0.2f%% - %d / %d / %d / %d / %d / %d",score, w1, w2, w3, w4, w5, miss) + end + self:x(self:GetParent():GetChild("Grade"):GetX()+(self:GetParent():GetChild("Grade"):GetWidth()*0.4)+5) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name = "ReplayAvailability", + InitCommand = function(self) + self:xy(scoreItemWidth-5,5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(1) + end, + SetCommand = function(self) + if scoreList[scoreIndex]:HasReplayData() then + self:settext("Replay Data Available.") + self:diffuse(getMainColor("enabled")) + else + self:settext("Replay Data Unavailable.") + self:diffuse(getMainColor("disabled")) + end + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + Name = "Date", + InitCommand = function(self) + self:xy(scoreItemWidth-5,-5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(1) + end, + SetCommand = function(self) + self:settext(scoreList[scoreIndex]:GetDate()) + end + } + + return t + end + + local function scoreDetail() + local scoreIndex + local t = Def.ActorFrame{ + InitCommand = function(self) + self:diffusealpha(0) + self:xy(scoreItemX, scoreItemY+scoreItemYSpacing+scoreItemHeight/2) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + scoreIndex = params.scoreIndex + inDetail = true + self:finishtweening() + self:xy(scoreItemX, (params.index+1)*(scoreItemHeight+scoreItemYSpacing)+100+scoreItemHeight/2) + self:easeOut(0.5) + self:xy(scoreItemX, scoreItemY+scoreItemYSpacing+scoreItemHeight/2) + self:diffusealpha(1) + end, + HideOnlineScoreDetailMessageCommand = function(self) + inDetail = false + self:playcommand("Hide") + end, + UpdateCLBListMessageCommand = function(self) + inDetail = false + self:playcommand("Hide") + end + } + + -- Watch online replay button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.2) + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:diffusealpha(0.4) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("Watch") + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.4) + end, + } + + -- View Online Profile Button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3 + 95,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.8) + end, + + TopPressedCommand = function(self) + if not inDetail then + return + end + self:finishtweening() + self:diffusealpha(1) + self:smooth(0.3) + self:diffusealpha(0.8) + local urlstring = "https://etternaonline.com/user/" .. scoreList[scoreIndex]:GetDisplayName() + GAMESTATE:ApplyGameCommand("urlnoexit," .. urlstring) + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3 + 95,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("View Profile") + end + } + + -- View Score On EtternaOnline Button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3 + 95 + 95,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.8) + end, + + TopPressedCommand = function(self) + if not inDetail then + return + end + self:finishtweening() + self:diffusealpha(1) + self:smooth(0.3) + self:diffusealpha(0.8) + local urlstring = "https://etternaonline.com/score/view/" .. scoreList[scoreIndex]:GetScoreid() .. scoreList[scoreIndex]:GetUserid() + GAMESTATE:ApplyGameCommand("urlnoexit," .. urlstring) + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3 + 95 + 95,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("View Online") + end + } + + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:diffusealpha(0.2) + self:halign(0):valign(0) + self:zoomto(scoreItemWidth, frameHeight-80) + end, + } + + t[#t+1] = LoadActor(THEME:GetPathG("","OffsetGraph"))..{ + InitCommand = function(self, params) + self:xy(5, 55) + end, + OnCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(offsetInput) + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + cheatIndex = params.scoreIndex + if scoreList[params.scoreIndex]:HasReplayData() then + DLMAN:RequestOnlineScoreReplayData( + scoreList[params.scoreIndex], + function() + MESSAGEMAN:Broadcast("DelayedShowOffset") + --self:playcommand("DelayedShowOffset") + end + ) + else + self:RunCommandsOnChildren(function(self) self:playcommand("Update", {width = scoreItemWidth-10, height = frameHeight-140,}) end) + end + end, + DelayedShowOffsetMessageCommand = function(self) + self:RunCommandsOnChildren(function(self) + local params = {width = scoreItemWidth-10, + height = frameHeight-140, + song = song, + steps = steps, + nrv = scoreList[cheatIndex]:GetNoteRowVector(), + dvt = scoreList[cheatIndex]:GetOffsetVector(), + ctt = scoreList[cheatIndex]:GetTrackVector(), + ntt = scoreList[cheatIndex]:GetTapNoteTypeVector(), + columns = steps:GetNumColumns()} + self:playcommand("Update", params) end + ) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(scoreItemWidth/2, (frameHeight-100)/2) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.6) + self:settext("No replay data\n(゜´Д`゜)") + end, + ShowOnlineScoreDetailMessageCommand = function(self, params) + if not scoreList[params.scoreIndex]:HasReplayData() then + self:settext("No replay data\n(゜´Д`゜)") + self:visible(true) + end + end, + DelayedShowOffsetMessageCommand = function(self) + if scoreList[cheatIndex]:HasReplayData() and scoreList[cheatIndex]:GetNoteRowVector() == nil then + self:settext("Missing Noterows from Online Replay\n(゜´Д`゜)") + else + self:settext("No replay data\n(゜´Д`゜)") + end + self:visible(not scoreList[cheatIndex]:HasReplayData() or scoreList[cheatIndex]:GetNoteRowVector() == nil) + end + } + + return t + + end + + for i=1, maxItems do + t[#t+1] = scoreListItem(i) + end + + t[#t+1] = scoreDetail() + + return t + +end + +local t = Def.ActorFrame { + OnCommand = function(self) + top = SCREENMAN:GetTopScreen() + MESSAGEMAN:Broadcast("SetStepsType",{st = stepsType}) + MESSAGEMAN:Broadcast("SetSteps",{steps = steps}) + scoreList = DLMAN:GetChartLeaderBoard(steps:GetChartKey(), currentCountry) + if #scoreList == 0 then + updateLeaderBoardForCurrentChart() + end + top:AddInputCallback(input) + end +} + +t[#t+1] = LoadActor("../_mouse") + +t[#t+1] = LoadActor("../_frame") + +t[#t+1] = topRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(0) + end +} + +t[#t+1] = stepsListRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(1) + end +} + +t[#t+1] = stepsBPMRow() .. { + InitCommand = function(self) + self:xy(160, 58) + self:delayedFadeIn(2) + end +} + +-- The main, central container (Online Leaderboard) +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X / 2, 110) + end, + + Def.Quad { + InitCommand = function (self) + self:zoomto(frameWidth,frameHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() then + movePage(1) + end + end + }, + LoadFont("Common Bold") .. { + InitCommand = function(self) + self:xy(5,10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Online Scores") + end + }, + LoadFont("Common Normal") .. { + Name = "RequestStatus", + InitCommand = function(self) + self:xy(5,30) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("") + end, + UpdateCLBListMessageCommand = function(self) + if #scoreList == 0 then + self:settext("Online scores not tracked or no scores recorded...") + else + self:settext("") + end + end + } + +} + +-- Current Rate/All Rates Toggle Button +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(10,155) + end, + + Def.Quad { + InitCommand = function(self) + self:diffuse(color("#000000")) + self:xy(0,0) + self:halign(0) + self:diffusealpha(0.8) + self:zoomto(150,25) + end + }, + + quadButton(6) .. { + Name = "ToggleRateFilter", + InitCommand = function(self) + self:diffuse(color("#FFFFFF")) + self:xy(0, 0) + self:halign(0) + self:diffusealpha(0) + self:zoomto(150, 25) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.0) + MESSAGEMAN:Broadcast("ToggleRateFilter") + updateLeaderBoardForCurrentChart() + end + }, + + LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(75, 0) + --self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:playcommand("Set") + end, + SetCommand = function(self) + if DLMAN:GetCurrentRateFilter() then + self:settext(filts[2]) + else + self:settext(filts[1]) + end + end, + ToggleRateFilterMessageCommand = function(self) + DLMAN:ToggleRateFilter() + self:playcommand("Set") + end + } +} + + +-- Top Scores/All Scores Toggle Button +t[#t+1] = Def.ActorFrame { + InitCommand = function(self) + self:xy(10,185) + end, + + Def.Quad { + InitCommand = function(self) + self:diffuse(color("#000000")) + self:xy(0,0) + self:halign(0) + self:diffusealpha(0.8) + self:zoomto(150,25) + end + }, + + quadButton(6) .. { + Name = "TopScoreToggle", + InitCommand = function(self) + self:diffuse(color("#FFFFFF")) + self:xy(0, 0) + self:halign(0) + self:diffusealpha(0) + self:zoomto(150, 25) + end, + TopPressedCommand = function(self) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.0) + MESSAGEMAN:Broadcast("TopScoreToggle") + updateLeaderBoardForCurrentChart() + end + }, + + LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(75, 0) + --self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:playcommand("Set") + end, + SetCommand = function(self) + if DLMAN:GetTopScoresOnlyFilter() then + self:settext(topfilts[1]) + else + self:settext(topfilts[2]) + end + end, + TopScoreToggleMessageCommand = function(self) + DLMAN:ToggleTopScoresOnlyFilter() + self:playcommand("Set") + end + } +} + + +t[#t+1] = scoreList() .. { + Name = "ScoreList", + InitCommand = function(self) + self:xy(SCREEN_CENTER_X / 2, 110) + self:delayedFadeIn(5) + lbActor = self + end +} + + +t[#t+1] = LoadActor("../_cursor") + +return t diff --git a/BGAnimations/ScreenNetChartLeaderboard underlay/default.lua b/BGAnimations/ScreenNetChartLeaderboard underlay/default.lua new file mode 100644 index 00000000..976d688a --- /dev/null +++ b/BGAnimations/ScreenNetChartLeaderboard underlay/default.lua @@ -0,0 +1,10 @@ +local t = Def.ActorFrame{} + +t[#t+1] = Def.Quad { + InitCommand = function(self) + self:diffusealpha(0.9) + self:FullScreen() + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetRoom decorations.lua b/BGAnimations/ScreenNetMusicInfo decorations/default.lua similarity index 53% rename from BGAnimations/ScreenNetRoom decorations.lua rename to BGAnimations/ScreenNetMusicInfo decorations/default.lua index dde5cd74..4a8f36a2 100644 --- a/BGAnimations/ScreenNetRoom decorations.lua +++ b/BGAnimations/ScreenNetMusicInfo decorations/default.lua @@ -1,5 +1,4 @@ -local t = Def.ActorFrame{} -t[#t+1] = LoadActor("_chatbox") +local t = Def.ActorFrame{} return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetMusicInfo out.lua b/BGAnimations/ScreenNetMusicInfo out.lua new file mode 100644 index 00000000..68e258cc --- /dev/null +++ b/BGAnimations/ScreenNetMusicInfo out.lua @@ -0,0 +1 @@ +return Def.ActorFrame{} diff --git a/BGAnimations/ScreenNetMusicInfo overlay/default.lua b/BGAnimations/ScreenNetMusicInfo overlay/default.lua new file mode 100644 index 00000000..141e12cc --- /dev/null +++ b/BGAnimations/ScreenNetMusicInfo overlay/default.lua @@ -0,0 +1,1127 @@ +local pn = GAMESTATE:GetEnabledPlayers()[1] +local song = GAMESTATE:GetCurrentSong() +local steps = GAMESTATE:GetCurrentSteps(pn) +local stepsType = steps:GetStepsType() + +local scoreList = {} +local maxItems = 10 +local maxPages = math.ceil(#scoreList/maxItems) +local curPage = 1 + +local inDetail = false +local transitioning = false + +local validStepsType = { + 'StepsType_Dance_Single', + 'StepsType_Dance_Solo', + 'StepsType_Dance_Double', +} +local maxNumDifficulties = 0 +for _,st in pairs(validStepsType) do + maxNumDifficulties = math.max(maxNumDifficulties, #song:GetStepsByStepsType(st)) +end + +local function getNextStepsType(n) + for i = 1, #validStepsType do + if validStepsType[i] == stepsType then + stepsType = validStepsType[(i+n-1+#validStepsType)%#validStepsType+1] -- 1 index scks + return stepsType + end + end +end + +local function movePage(n) + if n > 0 then + curPage = ((curPage+n-1) % maxPages + 1) + else + curPage = ((curPage+n+maxPages-1) % maxPages+1) + end + MESSAGEMAN:Broadcast("UpdateList") +end + +local function meterComparator(stepA, stepB) + local diffA = stepA:GetDifficulty() + local diffB = stepB:GetDifficulty() + + return Enum.Reverse(Difficulty)[diffA] < Enum.Reverse(Difficulty)[diffB] +end + +local function input(event) + if event.type == "InputEventType_FirstPress" then + if event.button == "Back" or event.button == "Start" then + SCREENMAN:GetTopScreen():Cancel() + end + + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + MESSAGEMAN:Broadcast("WheelUpSlow") + end + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + MESSAGEMAN:Broadcast("WheelDownSlow") + end + + if event.button == "EffectUp" and not inDetail then + changeMusicRate(0.05) + elseif event.button == "EffectDown" and not inDetail then + changeMusicRate(-0.05) + elseif event.button == "MenuLeft" and not inDetail then + movePage(-1) + elseif event.button == "MenuRight" and not inDetail then + movePage(1) + end + + local numpad = event.DeviceInput.button == "DeviceButton_KP "..event.char + if not numpad and event.char and tonumber(event.char) and not transitioning then + if tonumber(event.char) == 1 then + SCREENMAN:AddNewScreenToTop("ScreenFileTagManager") + elseif tonumber(event.char) == 2 then + SCREENMAN:AddNewScreenToTop("ScreenChartPreview") + elseif tonumber(event.char) == 3 and DLMAN:IsLoggedIn() then + SCREENMAN:AddNewScreenToTop("ScreenNetChartLeaderboard") + end + end + + end + + return false + +end + +local top +local replayScore + +local t = Def.ActorFrame { + OnCommand = function(self) + MESSAGEMAN:Broadcast("SetStepsType",{st = stepsType}) + MESSAGEMAN:Broadcast("SetSteps",{steps = steps}) + top = SCREENMAN:GetTopScreen() + top:AddInputCallback(input) + end, + TriggerExitFromMIMessageCommand = function(self, params) + self:sleep(0.1) + replayScore = params.score + transitioning = true + self:queuecommand("DelayedExitMI") + end, + DelayedExitMICommand = function(self) + MESSAGEMAN:Broadcast("TriggerReplayBegin", {score = replayScore}) + SCREENMAN:GetTopScreen():Cancel() + end +} + + +local function topRow() + local frameWidth = SCREEN_WIDTH - 20 + local frameHeight = 40 + + local t = Def.ActorFrame { + BeginCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + end + } + + t[#t+1] = Def.Sprite { + Name = "Banner", + InitCommand = function(self) + self:x(-frameWidth/2 + 5) + self:halign(0) + local bnpath = song:GetBannerPath() + if not bnpath then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) + self:scaletoclipped(96, 30) + end + } + + t[#t+1] = LoadFont("Common BLarge") .. { + Name = "SongTitle", + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, -9) + self:zoom(0.25) + self:halign(0) + self:settext(song:GetMainTitle()) + if #song:GetDisplaySubTitle() == 0 then + self:zoom(0.35):y(-5) + end + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + local actor = self:GetParent():GetChild("SongTitle") + local x = actor:GetX() + actor:GetWidth()*actor:GetZoomX() + 2 + local y = actor:GetY() - 2 + + self:xy(x,y) + self:zoom(0.3) + self:halign(0) + self:playcommand("Set") + end, + SetCommand = function(self) + local length = song:GetStepsSeconds()/getCurRateValue() + self:settextf("%s",SecondsToMSS(length)) + self:diffuse(getSongLengthColor(length)) + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 1) + self:zoom(0.35) + self:halign(0) + self:settext(song:GetDisplaySubTitle()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(-frameWidth/2 + 96 +10, 9) + self:zoom(0.35) + self:halign(0) + self:settext("// "..song:GetDisplayArtist()) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,-1) + self:zoom(0.5) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local diff = curSteps:GetDifficulty() + local stype = curSteps:GetStepsType() + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + meter = curSteps:GetMeter() + end + + local difftext + if diff == 'Difficulty_Edit' then + difftext = curSteps:GetDescription() + difftext = difftext == '' and getDifficulty(diff) or difftext + else + difftext = getDifficulty(diff) + end + + self:settext(ToEnumShortString(stype):gsub("%_"," ").." "..difftext.." "..meter) + self:diffuse(getDifficultyColor(GetCustomDifficulty(stype,diff))) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + + } + + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,9) + self:zoom(0.35) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + local notes = 0 + if curSteps ~= nil then + notes = curSteps:GetRadarValues(pn):GetValue("RadarCategory_Notes") + end + self:settextf("%d Notes", notes) + self:diffuse(Saturation(getDifficultyColor(GetCustomDifficulty(curSteps:GetStepsType(),curSteps:GetDifficulty())),0.3)) + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name="MSDAvailability", + InitCommand = function(self) + self:xy(frameWidth/2-5,-11) + self:zoom(0.30) + self:halign(1) + self:playcommand("Set", {steps = steps}) + end, + SetCommand = function(self, params) + local curSteps = params.steps + if curSteps ~= nil then + + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + self:settext("Default") + self:diffuse(color(colorConfig:get_data().main.disabled)) + else + self:settext("MSD") + self:diffuse(color(colorConfig:get_data().main.enabled)) + end + end + end, + SetStepsMessageCommand = function(self, params) + self:playcommand("Set",{steps = params.steps}) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "round_star")) .. { + InitCommand = function(self) + self:xy(-frameWidth/2+1,-frameHeight/2+1) + self:zoom(0.3) + self:wag() + self:diffuse(Color.Yellow) + + if not song:IsFavorited() then + self:visible(false) + end + end + } + + return t +end + + +local function stepsListRow() + local frameWidth = 150 + local frameHeight = 25 + local topRowFrameWidth = SCREEN_WIDTH - 20 + local topRowFrameHeight = 40 + + + local stepsTable = {} + local t = Def.ActorFrame{ + SetStepsTypeMessageCommand = function(self, params) + stepsTable = song:GetStepsByStepsType(params.st) + table.sort(stepsTable, meterComparator) + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, frameHeight) + self:xy(-topRowFrameWidth/2, topRowFrameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(0) + end + + } + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(-topRowFrameWidth/2, topRowFrameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(0) + self:faderight(0.5) + end, + TopPressedCommand = function(self, params) + MESSAGEMAN:Broadcast("SetStepsType", {st = getNextStepsType(-1)}) + self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(-topRowFrameWidth/2+frameWidth/2, topRowFrameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(0) + self:fadeleft(0.5) + end, + TopPressedCommand = function(self, params) + MESSAGEMAN:Broadcast("SetStepsType", {st = getNextStepsType(1)}) + self:GetParent():GetChild("TriangleRight"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleLeft", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(-topRowFrameWidth/2+10,topRowFrameHeight) + self:rotationz(-90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleRight", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(-topRowFrameWidth/2+frameWidth-10,topRowFrameHeight) + self:rotationz(90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:zoom(0.4) + self:xy(-topRowFrameWidth/2+frameWidth/2,topRowFrameHeight) + end, + SetCommand = function(self) + self:settext(ToEnumShortString(stepsType):gsub("%_"," ")) + end + } + + for i = 1, maxNumDifficulties do + + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(40, frameHeight) + self:y(topRowFrameHeight) + self:diffuse(color("#000000")):diffusealpha(0) + self:halign(0) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) + end, + SetCommand = function(self) + local curSteps = stepsTable[i] + if curSteps then + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowCommand = function(self) + self:y(topRowFrameHeight) + self:finishtweening() + self:sleep((i-1)*0.03) + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)) + self:diffusealpha(0.8) + end, + HideCommand = function(self) + self:diffusealpha(0) + self:y(SCREEN_HEIGHT*10) + self:x((-topRowFrameWidth/2)+frameWidth+5+45*(i-1)-10) + end, + TopPressedCommand = function(self) + MESSAGEMAN:Broadcast("SetSteps", {steps = stepsTable[i]}) + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + local stype = steps:GetStepsType() + self:zoom(0.4) + self:diffusealpha(0) + self:xy((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10, topRowFrameHeight) + self:settext("0") + end, + SetCommand = function(self) + local curSteps = stepsTable[i] + if curSteps then + + local meter = math.floor(curSteps:GetMSD(getCurRateValue(),1)) + if meter == 0 then + meter = curSteps:GetMeter() + end + + self:settext(meter) + self:diffuse(color(colorConfig:get_data().difficulty[curSteps:GetDifficulty()])) + self:diffusealpha(0) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowCommand = function(self) + self:finishtweening() + self:sleep((i-1)*0.05) + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:finishtweening() + self:easeOut(1) + self:x((-topRowFrameWidth/2)+frameWidth+25+45*(i-1)-10) + self:diffusealpha(0) + end + } + end + + + return t +end + +local function stepsBPMRow() + local topRowFrameWidth = SCREEN_WIDTH - 20 + local topRowFrameHeight = 40 + local frameWidth = 150 + local frameHeight = 25 + local t = Def.ActorFrame{} + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:zoomto(frameWidth, 25) + self:xy(topRowFrameWidth/2, topRowFrameHeight) + self:diffuse(color("#000000")):diffusealpha(0.8) + self:halign(1) + end + } + + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(topRowFrameWidth/2-frameWidth/2, topRowFrameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:faderight(0.5) + end, + TopPressedCommand = function(self, params) + changeMusicRate(-0.05) + self:GetParent():GetChild("TriangleLeft"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + t[#t+1] = quadButton(6)..{ + InitCommand = function(self) + self:zoomto(frameWidth/2, frameHeight) + self:xy(topRowFrameWidth/2, topRowFrameHeight) + self:diffuse(color("#FFFFFF")):diffusealpha(0) + self:halign(1) + self:fadeleft(0.5) + end, + TopPressedCommand = function(self, params) + changeMusicRate(0.05) + self:GetParent():GetChild("TriangleRight"):playcommand("Tween") + + self:finishtweening() + self:diffusealpha(0.2) + self:smooth(0.3) + self:diffusealpha(0) + end + } + + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleLeft", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(topRowFrameWidth/2-frameWidth+10,topRowFrameHeight) + self:rotationz(-90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { + Name = "TriangleRight", + InitCommand = function(self) + self:zoom(0.15) + self:diffusealpha(0.8) + self:xy(topRowFrameWidth/2-10,topRowFrameHeight) + self:rotationz(90) + end, + TweenCommand = function(self) + self:finishtweening() + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + self:smooth(0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) + end + } + + t[#t+1] = LoadFont("Common Bold") .. { + InitCommand = function(self) + self:zoom(0.35) + self:xy(topRowFrameWidth/2-75,topRowFrameHeight-4) + end, + SetStepsMessageCommand = function(self, params) + if params.steps then + local bpms = steps:GetTimingData():GetActualBPM() + if bpms[1] == bpms[2] and bpms[1]~= nil then + self:settext(string.format("BPM: %d",bpms[1]*getCurRateValue())) + else + self:settext(string.format("BPM: %d-%d (%d)",bpms[1]*getCurRateValue(),bpms[2]*getCurRateValue(),getCommonBPM(song:GetTimingData():GetBPMsAndTimes(true),song:GetLastBeat()))) + end + end + end + } + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:zoom(0.3) + self:xy(topRowFrameWidth/2-75,topRowFrameHeight+4) + end, + SetStepsMessageCommand = function(self, params) + self:settext(getCurRateDisplayString()) + end + } + + return t +end + +local function offsetInput(event) + if event.type == "InputEventType_FirstPress" and inDetail then + local outputName = "" + if event.button == "EffectUp" then + outputName = "NextJudge" + elseif event.button == "EffectDown" then + outputName = "PrevJudge" + elseif event.button == "MenuDown" then + outputName = "ToggleHands" + elseif event.button == "MenuUp" then + outputName = "ResetJudge" + end + + if outputName ~= "" then + MESSAGEMAN:Broadcast("OffsetPlotModification", {Name = outputName}) + end + end +end + +local function scoreList() + local frameWidth = 430 + local frameHeight = 340 + local t = Def.ActorFrame{ + SetStepsMessageCommand = function(self, params) + steps = params.steps + scoreList = getScoreTable(pn, getCurRate(), steps) + curPage = 1 + if scoreList ~= nil then + maxPages = math.ceil(#scoreList/maxItems) + MESSAGEMAN:Broadcast("UpdateList") + self:GetChild("NoScore"):visible(false) + else + maxPages = 1 + self:RunCommandsOnChildren(function(self) self:playcommand("Hide") end) + self:GetChild("NoScore"):visible(true):playcommand("Set") + end + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function (self) + self:zoomto(frameWidth,frameHeight) + self:halign(0):valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end, + WheelUpSlowMessageCommand = function(self) + if self:isOver() and SCREENMAN:GetTopScreen():GetName() == "ScreenMusicInfo" then + movePage(-1) + end + end, + WheelDownSlowMessageCommand = function(self) + if self:isOver() and SCREENMAN:GetTopScreen():GetName() == "ScreenMusicInfo" then + movePage(1) + end + end + } + + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(5, 10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Scores") + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name = "NoScore", + InitCommand = function(self) + self:xy(frameWidth/2, frameHeight/2) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.6) + self:settext("No scores here!\n(* ` ω´)") + end, + SetCommand = function(self) + self:finishtweening() + self:y(frameHeight/2-5) + self:easeOut(0.5) + self:y(frameHeight/2) + end + } + + local scoreItemWidth = frameWidth-30 + local scoreItemHeight = 25 + + local scoreItemX = 20 + local scoreItemY = 30+scoreItemHeight/2 + local scoreItemYSpacing = 5 + + local function scoreListItem(i) + local scoreIndex = (curPage-1)*10+i + local detail = false + + local t = Def.ActorFrame{ + InitCommand = function(self) + self:diffusealpha(0) + self:xy(scoreItemX, scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)-10) + end, + ShowCommand = function(self) + self:y(scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)-10) + self:diffusealpha(0) + self:finishtweening() + self:sleep((i-1)*0.03) + self:easeOut(1) + self:y(scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)) + self:diffusealpha(1) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + self:y(SCREEN_HEIGHT*10) -- Throw it offscreen + end, + UpdateListMessageCommand = function(self) + detail = false + scoreIndex = (curPage-1)*10+i + if scoreList ~= nil and scoreList[scoreIndex] ~= nil then + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + self:playcommand("Show") + else + self:playcommand("Hide") + end + end, + ShowScoreDetailMessageCommand = function(self, params) + if params.index == i then + detail = true + self:finishtweening() + self:easeOut(0.5) + self:y(scoreItemY) + self:valign(0) + else + self:playcommand("Hide") + end + end, + HideScoreDetailMessageCommand = function(self) + detail = false + if scoreList ~= nil and scoreList[scoreIndex] ~= nil then + self:playcommand("Show") + end + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(-10,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + end, + SetCommand = function(self) + self:settextf("%d", scoreIndex) + end + } + + t[#t+1] = quadButton(6) .. { + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.2) + self:zoomto(scoreItemWidth, scoreItemHeight) + end, + TopPressedCommand = function(self, params) + self:finishtweening() + self:diffusealpha(0.4) + self:smooth(0.3) + self:diffusealpha(0.2) + if params.input == "DeviceButton_left mouse button" then + if not detail then + MESSAGEMAN:Broadcast("ShowScoreDetail", {index = i, scoreIndex = scoreIndex}) + end + elseif params.input == "DeviceButton_right mouse button" then + MESSAGEMAN:Broadcast("HideScoreDetail") + end + end, + SetCommand = function(self) + if scoreList[i]:GetEtternaValid() then + self:diffuse(color("#FFFFFF")) + else + self:diffuse(color(colorConfig:get_data().clearType.ClearType_Invalid)) + end + self:diffusealpha(0.2) + end + } + + t[#t+1] = getClearTypeLampQuad(3, scoreItemHeight)..{ + InitCommand = function(self) + self:halign(0) + self:diffusealpha(0.8) + end, + SetCommand = function(self) + self:playcommand("SetClearType", {clearType = getClearType(pn,steps,scoreList[scoreIndex])}) + end + } + + + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(20,0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + end, + SetCommand = function(self) + local ssr = scoreList[scoreIndex]:GetSkillsetSSR("Overall") + self:settextf("%0.2f",ssr) + self:diffuse(getMSDColor(ssr)) + end + } + + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(40,-6) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:halign(0) + end, + SetCommand = function(self) + local clearType = getClearType(pn,steps,scoreList[scoreIndex]) + + self:settext(getClearTypeText(clearType)) + self:diffuse(getClearTypeColor(clearType)) + end + } + + t[#t+1] = LoadFont("Common Bold")..{ + Name = "Grade", + InitCommand = function(self) + self:xy(40,5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:halign(0) + end, + SetCommand = function(self) + local grade = scoreList[scoreIndex]:GetWifeGrade() + self:settext(THEME:GetString("Grade",ToEnumShortString(grade))) + self:diffuse(getGradeColor(grade)) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name = "PercentScore", + InitCommand = function(self) + self:xy(40,5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(0) + end, + SetCommand = function(self) + local score = scoreList[scoreIndex]:GetWifeScore() + local w1 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W1") + local w2 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W2") + local w3 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W3") + local w4 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W4") + local w5 = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_W5") + local miss = scoreList[scoreIndex]:GetTapNoteScore("TapNoteScore_Miss") + self:settextf("%0.2f%% - %d / %d / %d / %d / %d / %d",math.floor(score*10000)/100, w1, w2, w3, w4, w5, miss) + self:x(self:GetParent():GetChild("Grade"):GetX()+(self:GetParent():GetChild("Grade"):GetWidth()*0.4)+5) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name = "ReplayAvailability", + InitCommand = function(self) + self:xy(scoreItemWidth-5,5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(1) + end, + SetCommand = function(self) + if scoreList[scoreIndex]:HasReplayData() then + self:settext("Replay Data Available.") + self:diffuse(getMainColor("enabled")) + else + self:settext("Replay Data Unavailable.") + self:diffuse(getMainColor("disabled")) + end + end + } + + t[#t+1] = LoadFont("Common Normal") .. { + Name = "Date", + InitCommand = function(self) + self:xy(scoreItemWidth-5,-5) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:halign(1) + end, + SetCommand = function(self) + self:settext(scoreList[scoreIndex]:GetDate()) + end + } + + return t + end + + local function scoreDetail() + local scoreIndex + local t = Def.ActorFrame{ + InitCommand = function(self) + self:diffusealpha(0) + self:xy(scoreItemX, scoreItemY+scoreItemYSpacing+scoreItemHeight/2) + end, + HideCommand = function(self) + self:stoptweening() + self:easeOut(0.5) + self:diffusealpha(0) + end, + ShowScoreDetailMessageCommand = function(self, params) + scoreIndex = params.scoreIndex + inDetail = true + self:finishtweening() + self:xy(scoreItemX, (params.index+1)*(scoreItemHeight+scoreItemYSpacing)+100+scoreItemHeight/2) + self:easeOut(0.5) + self:xy(scoreItemX, scoreItemY+scoreItemYSpacing+scoreItemHeight/2) + self:diffusealpha(1) + end, + HideScoreDetailMessageCommand = function(self) + inDetail = false + self:playcommand("Hide") + end, + UpdateListMessageCommand = function(self) + inDetail = false + self:playcommand("Hide") + end + } + + -- Watch online replay button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.2) + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:diffusealpha(0.4) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("Watch") + end, + ShowScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.4) + end, + } + + -- View eval screen for score button + t[#t+1] = quadButton(3)..{ + InitCommand = function (self) + self:xy(95/2+3 + 95,30) + self:zoomto(90,20) + self:diffuse(color(colorConfig:get_data().main.disabled)) + end, + ShowScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.2) + end + } + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(95/2+3 + 95,30) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:diffusealpha(0.4) + self:queuecommand('Set') + end, + SetCommand = function(self) + self:settext("View Eval") + end, + ShowScoreDetailMessageCommand = function(self, params) + self:diffusealpha(0.4) + end, + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:diffusealpha(0.2) + self:halign(0):valign(0) + self:zoomto(scoreItemWidth, frameHeight-80) + end, + } + + t[#t+1] = LoadActor(THEME:GetPathG("","OffsetGraph"))..{ + InitCommand = function(self, params) + self:xy(5, 55) + end, + OnCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(offsetInput) + end, + ShowScoreDetailMessageCommand = function(self, params) + + if scoreList[params.scoreIndex]:HasReplayData() then + self:RunCommandsOnChildren(function(self) + local params = {width = scoreItemWidth-10, + height = frameHeight-140, + song = song, + steps = steps, + nrv = scoreList[params.scoreIndex]:GetNoteRowVector(), + dvt = scoreList[params.scoreIndex]:GetOffsetVector(), + ctt = scoreList[params.scoreIndex]:GetTrackVector(), + ntt = scoreList[params.scoreIndex]:GetTapNoteTypeVector(), + columns = steps:GetNumColumns()} + self:playcommand("Update", params) end + ) + else + self:RunCommandsOnChildren(function(self) self:playcommand("Update", {width = scoreItemWidth-10, height = frameHeight-140,}) end) + end + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(scoreItemWidth/2, (frameHeight-100)/2) + self:zoom(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.6) + self:settext("No replay data\n(゜´Д`゜)") + + end, + ShowScoreDetailMessageCommand = function(self, params) + self:visible(not scoreList[params.scoreIndex]:HasReplayData()) + end + } + + return t + + end + + for i=1, maxItems do + t[#t+1] = scoreListItem(i) + end + + t[#t+1] = scoreDetail() + + return t + +end + +-- NO CLUE WHY THE PARENT ACTOR WON'T RECIEVE THESE BROADCASTS +t[#t+1] = Def.Actor{ + SetStepsMessageCommand = function(self, params) + steps = params.steps + end, + CurrentRateChangedMessageCommand = function(self) + MESSAGEMAN:Broadcast("SetSteps",{steps = steps}) + end +} + +t[#t+1] = topRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(0) + end +} + +t[#t+1] = stepsListRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(1) + end +} + +t[#t+1] = stepsBPMRow() .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, 50) + self:delayedFadeIn(2) + end +} + +t[#t+1] = LoadActor("stepsinfo") .. { + InitCommand = function(self) + self:xy(capWideScale(135,160),140) + self:delayedFadeIn(3) + end +} + +t[#t+1] = LoadActor("ssrbreakdown") .. { + InitCommand = function(self) + self:xy(capWideScale(135,160),315) + self:delayedFadeIn(4) + end +} + +t[#t+1] = scoreList() .. { + Name = "ScoreList", + InitCommand = function(self) + self:xy(320,110) + self:delayedFadeIn(5) + end +} + + + + + +t[#t+1] = LoadActor("../_mouse") + +t[#t+1] = LoadActor("../_frame") + +local tab = TAB:new({"Manage Tags", "Preview", "Leaderboard", "", ""}) +t[#t+1] = tab:makeTabActors() .. { + OnCommand = function(self) + if IsNetSMOnline() and IsSMOnlineLoggedIn(PLAYER_1) and NSMAN:IsETTP() then + self:y(SCREEN_HEIGHT+tab.height/2 - 17) + self:easeOut(0.5) + self:y(SCREEN_HEIGHT-tab.height/2 - 17) + else + self:y(SCREEN_HEIGHT+tab.height/2) + self:easeOut(0.5) + self:y(SCREEN_HEIGHT-tab.height/2) + end + end, + OffCommand = function(self) + self:y(SCREEN_HEIGHT+tab.height/2) + end, + TabPressedMessageCommand = function(self, params) + if params.name == "Manage Tags" then + SCREENMAN:AddNewScreenToTop("ScreenFileTagManager") + elseif params.name == "Preview" then + SCREENMAN:AddNewScreenToTop("ScreenChartPreview") + elseif params.name == "Leaderboard" and DLMAN:IsLoggedIn() then + SCREENMAN:AddNewScreenToTop("ScreenNetChartLeaderboard") + end + end +} + +t[#t+1] = LoadActor("../_cursor") + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetMusicInfo overlay/ssrbreakdown.lua b/BGAnimations/ScreenNetMusicInfo overlay/ssrbreakdown.lua new file mode 100644 index 00000000..41b285f8 --- /dev/null +++ b/BGAnimations/ScreenNetMusicInfo overlay/ssrbreakdown.lua @@ -0,0 +1,145 @@ +local t = Def.ActorFrame{} +local circleRadius = 100 +local maxValue = 30 +local softCap = 40/30 +local frameWidth = capWideScale(250,300) +local frameHeight = 270 + + +local SkillSets = { + "Stream", + "Jumpstream", + "Handstream", + "Stamina", + "JackSpeed", + "Chordjack", + "Technical" +} + + + +-- Angle in degrees +local function getPointOffset(distance, angle) + local rad = math.rad(angle) + return math.cos(rad)*distance, math.sin(rad)*distance +end + +t[#t+1] = Def.Quad{ + InitCommand = function (self) + self:zoomto(frameWidth,frameHeight) + self:diffuse(color(colorConfig:get_data().main.frame)):diffusealpha(0.8) + end +} + +t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(-frameWidth/2+5, -frameHeight/2+10) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("MSD Breakdown") + end +} + +local sepAngle = 360/#SkillSets-1 +local verts = {} +local maxVerts = {} + +local function makeMSDPoints(i) + return LoadFont("Common Normal")..{ + InitCommand = function(self) + local x,y = getPointOffset(circleRadius,sepAngle*(i-1)-90) + self:xy(x,y) + self:zoom(0.3) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + end, + SetStepsMessageCommand = function(self, params) + local steps = params.steps + local MSD = steps:GetMSD(getCurRateValue(), i+1) + self:settextf("%s\n%0.2f",SkillSets[i], MSD) + self:AddAttribute(#SkillSets[i], {Length = -1, Diffuse = getMSDColor(MSD)}) + end + } +end + +t[#t+1] = Def.ActorMultiVertex{ + Name= "SSR_MAX_Graph", + InitCommand = function(self) + local x,y + for i=1, #SkillSets do + x,y = getPointOffset(circleRadius,sepAngle*(i-1)-90) + + maxVerts[#maxVerts+1] = {{x,y,0},color("#FFFFFF66")} + maxVerts[#maxVerts+1] = {{0,0,0},color("#FFFFFF66")} + end + + maxVerts[#maxVerts+1] = maxVerts[1] + maxVerts[#maxVerts+1] = {{0,0,0},color("#FFFFFF66")} + + self:SetDrawState{First= 1, Num= -1} + self:SetDrawState{Mode="DrawMode_QuadStrip"} + self:playcommand("Set") + end, + SetCommand = function(self) + self:diffusealpha(0.2) + self:SetVertices(maxVerts) + self:SetDrawState{First= 1, Num= -1} + end +} + +t[#t+1] = Def.ActorMultiVertex{ + Name= "SSR_Graph", + InitCommand = function(self) + self:SetDrawState{Mode="DrawMode_QuadStrip"} + self:queuecommand("Set") + self:diffusealpha(0.5) + end, + SetCommand = function(self) + self:finishtweening() + self:easeOut(1) + self:SetVertices(verts) + self:SetDrawState{First= 1, Num= -1} + end, + SetStepsMessageCommand = function(self, params) + verts = {} + local steps = params.steps + local x,y + local overallMSD = steps:GetMSD(getCurRateValue(), 1) + local MSD + for i=1, #SkillSets do + x,y = getPointOffset(circleRadius,sepAngle*(i-1)-90) + MSD = steps:GetMSD(getCurRateValue(), i+1) + + verts[#verts+1] = {{x*math.min(softCap,MSD/maxValue),y*math.min(softCap,MSD/maxValue),0},getMSDColor(MSD)} + verts[#verts+1] = {{0,0,0},color("#FFFFFF")} + end + + verts[#verts+1] = verts[1] + verts[#verts+1] = {{0,0,0},color("#FFFFFF")} + + self:playcommand("Set") + end +} + +for i=1, #SkillSets do + t[#t+1] = makeMSDPoints(i) +end + +t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(frameWidth/2-5, frameHeight/2-10) + self:zoom(0.35) + self:halign(1) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:settext("Overall:") + end, + SetStepsMessageCommand = function(self, params) + local steps = params.steps + local MSD = steps:GetMSD(getCurRateValue(), 1) + self:settextf("Overall: %0.2f", MSD) + self:AddAttribute(8, {Length = -1, Diffuse = getMSDColor(MSD)}) + end +} + + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetMusicInfo overlay/stepsinfo.lua b/BGAnimations/ScreenNetMusicInfo overlay/stepsinfo.lua new file mode 100644 index 00000000..941ee166 --- /dev/null +++ b/BGAnimations/ScreenNetMusicInfo overlay/stepsinfo.lua @@ -0,0 +1,70 @@ + +local t = Def.ActorFrame{} + +local frameWidth = capWideScale(250,300) +local frameHeight = 60 + +local pn = GAMESTATE:GetEnabledPlayers()[1] +local song = GAMESTATE:GetCurrentSong() +local steps = GAMESTATE:GetCurrentSteps(pn) + +t[#t+1] = Def.Quad{ + InitCommand = function (self) + self:zoomto(frameWidth,frameHeight) + self:diffuse(color(colorConfig:get_data().main.frame)):diffusealpha(0.8) + end +} + +t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(-frameWidth/2+5,frameHeight/2-8) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + self:settextf("ChartKey: %s","") + end, + SetStepsMessageCommand = function(self, params) + self:settextf("ChartKey: %s",params.steps:GetChartKey()) + end +} + + +local parameters = { + {"Notes","RadarCategory_Notes"}, + {"Jumps","RadarCategory_Jumps"}, + {"Hands","RadarCategory_Hands"}, + {"Holds","RadarCategory_Holds"}, + {"Rolls","RadarCategory_Rolls"}, + {"Mines","RadarCategory_Mines"}, + {"Lifts","RadarCategory_Lifts"}, + {"Fakes","RadarCategory_Fakes"} +} + +for i,v in ipairs(parameters) do + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy((-frameWidth/2)+frameWidth/(#parameters+1)*i,-10) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.4) + self:settext(v[1]) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy((-frameWidth/2)+frameWidth/(#parameters+1)*i,3) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + self:zoom(0.3) + end, + SetStepsMessageCommand = function(self, params) + self:settext(params.steps:GetRadarValues(pn):GetValue(v[2])) + self:finishtweening() + self:diffusealpha(0):y(0) + self:easeOut(1) + self:diffusealpha(1):y(3) + end + } + +end + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetMusicInfo underlay/default.lua b/BGAnimations/ScreenNetMusicInfo underlay/default.lua new file mode 100644 index 00000000..c7a31b85 --- /dev/null +++ b/BGAnimations/ScreenNetMusicInfo underlay/default.lua @@ -0,0 +1,10 @@ +local t = Def.ActorFrame{} + +t[#t+1] = Def.Quad { + InitCommand = function(self) + self:diffusealpha(0.8) + self:FullScreen() + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetRoom decorations/default.lua b/BGAnimations/ScreenNetRoom decorations/default.lua new file mode 100644 index 00000000..1bd9a97e --- /dev/null +++ b/BGAnimations/ScreenNetRoom decorations/default.lua @@ -0,0 +1,20 @@ +local t = Def.ActorFrame{} + +t[#t+1] = Def.ActorFrame { + InitCommand=function(self) + self:rotationz(-90):xy(SCREEN_CENTER_X/2-WideScale(get43size(150),150),270) + self:delayedFadeIn(5) + end, + OffCommand=function(self) + self:stoptweening() + self:sleep(0.025) + self:smooth(0.2) + self:diffusealpha(0) + end, + + OnCommand=function(self) + wheel = SCREENMAN:GetTopScreen():GetMusicWheel() + end, +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetRoom overlay/default.lua b/BGAnimations/ScreenNetRoom overlay/default.lua new file mode 100644 index 00000000..3c9e97a8 --- /dev/null +++ b/BGAnimations/ScreenNetRoom overlay/default.lua @@ -0,0 +1,47 @@ +local pn = GAMESTATE:GetEnabledPlayers()[1] +local profile = GetPlayerOrMachineProfile(pn) + +local user = playerConfig:get_data(pn_to_profile_slot(pn)).Username +local pass = playerConfig:get_data(pn_to_profile_slot(pn)).Password +if isAutoLogin() then + DLMAN:LoginWithToken(user, pass) +end + +local replayScore +local isEval + +local t = Def.ActorFrame{ + LoginFailedMessageCommand = function(self) + SCREENMAN:SystemMessage("Login Failed!") + end, + + LoginMessageCommand=function(self) + SCREENMAN:SystemMessage("Login Successful!") + GHETTOGAMESTATE:setOnlineStatus("Online") + end, + + LogOutMessageCommand=function(self) + SCREENMAN:SystemMessage("Logged Out!") + GHETTOGAMESTATE:setOnlineStatus("Local") + end +} + + +t[#t+1] = Def.Quad{ + InitCommand=function(self) + self:y(SCREEN_HEIGHT):halign(0):valign(1):zoomto(SCREEN_WIDTH,200):diffuse(getMainColor("background")):fadetop(1) + end +} + + +t[#t+1] = LoadActor("../_frame") +t[#t+1] = LoadActor("tabs") + +t[#t+1] = StandardDecorationFromFileOptional("BPMDisplay","BPMDisplay") +t[#t+1] = StandardDecorationFromFileOptional("BPMLabel","BPMLabel") +t[#t+1] = LoadActor("../_cursor") + +local largeImageText = string.format("%s: %5.2f",profile:GetDisplayName(), profile:GetPlayerRating()) +GAMESTATE:UpdateDiscordMenu(largeImageText) + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetRoom overlay/tabs.lua b/BGAnimations/ScreenNetRoom overlay/tabs.lua new file mode 100644 index 00000000..e59a4ce1 --- /dev/null +++ b/BGAnimations/ScreenNetRoom overlay/tabs.lua @@ -0,0 +1,59 @@ +local function input(event) + + if event.type == "InputEventType_FirstPress" then + + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + wheel:Move(-1) + wheel:Move(0) + end + + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + wheel:Move(1) + wheel:Move(0) + end + + if event.DeviceInput.button == "DeviceButton_middle mouse button" then + lastY = INPUTFILTER:GetMouseY() + end + + end + + if event.type == "InputEventType_Repeat" then + if event.DeviceInput.button == "DeviceButton_middle mouse button" then + curY = INPUTFILTER:GetMouseY() + if curY-lastY > 0 then + wheel:Move(math.floor((curY-lastY)/50)) + elseif curY-lastY < 0 then + wheel:Move(math.ceil((curY-lastY)/50)) + end + wheel:Move(0) + end + end + + return false + +end + +local lastY +local curY + +local top +local wheel +local t = Def.ActorFrame{ + BeginCommand = function(self) + top = SCREENMAN:GetTopScreen() + wheel = SCREENMAN:GetTopScreen():GetMusicWheel() + top:AddInputCallback(input) + self:diffusealpha(0) + self:smooth(0.5) + self:diffusealpha(1) + end, + OffCommand = function(self) + self:smooth(0.5) + self:diffusealpha(0) + end +} + +t[#t+1] = LoadActor("../_mouse") + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetRoom underlay.lua b/BGAnimations/ScreenNetRoom underlay.lua deleted file mode 100644 index fe657b95..00000000 --- a/BGAnimations/ScreenNetRoom underlay.lua +++ /dev/null @@ -1,5 +0,0 @@ -local t = Def.ActorFrame{} -t[#t+1] = LoadActor("_background") -t[#t+1] = LoadActor("_particles"); - -return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetRoom underlay/default.lua b/BGAnimations/ScreenNetRoom underlay/default.lua new file mode 100644 index 00000000..382a8b22 --- /dev/null +++ b/BGAnimations/ScreenNetRoom underlay/default.lua @@ -0,0 +1,9 @@ +local t = Def.ActorFrame { + BeginCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end +} +t[#t+1] = LoadActor("../_background") +t[#t+1] = LoadActor("../_particles") + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetSelectBase overlay/currentsort.lua b/BGAnimations/ScreenNetSelectBase overlay/currentsort.lua deleted file mode 100644 index d28ef7f1..00000000 --- a/BGAnimations/ScreenNetSelectBase overlay/currentsort.lua +++ /dev/null @@ -1,112 +0,0 @@ -local frameWidth = 280 -local frameHeight = 20 -local frameX = SCREEN_WIDTH -local frameY = 10 - -local sortTable = { - SortOrder_Preferred = 'Preferred', - SortOrder_Group = 'Group', - SortOrder_Title = 'Title', - SortOrder_BPM = 'BPM', - SortOrder_Popularity = 'Popular', - SortOrder_TopGrades = 'Grade', - SortOrder_Artist = 'Artist', - SortOrder_Genre = 'Genre', - SortOrder_BeginnerMeter = 'Beginner Meter', - SortOrder_EasyMeter = 'Easy Meter', - SortOrder_MediumMeter = 'Normal Meter', - SortOrder_HardMeter = 'Hard Meter', - SortOrder_ChallengeMeter = 'Insane Meter', - SortOrder_DoubleEasyMeter = 'Double Easy Meter', - SortOrder_DoubleMediumMeter = 'Double Normal Meter', - SortOrder_DoubleHardMeter = 'Double Hard Meter', - SortOrder_DoubleChallengeMeter = 'Double Insane Meter', - SortOrder_ModeMenu = 'Mode Menu', - SortOrder_AllCourses = 'All Courses', - SortOrder_Nonstop = 'Nonstop', - SortOrder_Oni = 'Oni', - SortOrder_Endless = 'Endless', - SortOrder_Length = 'Song Length', - SortOrder_Roulette = 'Roulette', - SortOrder_Recent = 'Recently Played' -}; - -local t = Def.ActorFrame{ - InitCommand = function(self) - self:xy(frameX,frameY) - end; - OnCommand = function(self) - self:y(-frameHeight/2) - self:smooth(0.5) - self:y(frameY) - end; - OffCommand = function(self) - self:smooth(0.5) - self:y(-frameHeight/2) - end; -}; - - -t[#t+1] = Def.Quad{ - Name="CurrentSort"; - InitCommand=function(self) - self:halign(1):zoomto(frameWidth,frameHeight):diffuse(getMainColor('highlight')) - end; - -}; - -t[#t+1] = LoadFont("Common Normal") .. { - InitCommand=function(self) - self:x(5-frameWidth):halign(0):zoom(0.45):maxwidth((frameWidth-40)/0.45) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - self:diffuse(color(colorConfig:get_data().main.headerFrameText)) - local sort = GAMESTATE:GetSortOrder() - local song = GAMESTATE:GetCurrentSong() - if sort == nil then - self:settext("Sort: ") - elseif sort == "SortOrder_Group" and song ~= nil then - self:settext(song:GetGroupName()) - else - self:settext("Sort: "..sortTable[sort]) - end - - end; - SortOrderChangedMessageCommand=function(self) - self:queuecommand("Set") - end; - CurrentSongChangedMessageCommand=function(self) - self:queuecommand("Set") - end; -}; - -t[#t+1] = LoadFont("Common Normal") .. { - InitCommand=function(self) - self:x(-5):halign(1):zoom(0.3):maxwidth(40/0.45) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - self:diffuse(color(colorConfig:get_data().main.headerFrameText)) - local top = SCREENMAN:GetTopScreen() - if top:GetName() == "ScreenSelectMusic" or top:GetName() == "ScreenNetSelectMusic" then - local wheel = top:GetChild("MusicWheel") - self:settextf("%d/%d",wheel:GetCurrentIndex()+1,wheel:GetNumItems()) - elseif top:GetName() == "ScreenNetRoom" then - local wheel = top:GetChild("RoomWheel") - self:settextf("%d/%d",wheel:GetCurrentIndex()+1,wheel:GetNumItems()) - end; - end; - SortOrderChangedMessageCommand=function(self) - self:queuecommand("Set") - end; - CurrentSongChangedMessageCommand=function(self) - self:queuecommand("Set") - end; -}; - -return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetSelectBase overlay/default.lua b/BGAnimations/ScreenNetSelectBase overlay/default.lua deleted file mode 100644 index 6fa3a4d3..00000000 --- a/BGAnimations/ScreenNetSelectBase overlay/default.lua +++ /dev/null @@ -1,17 +0,0 @@ -local t = Def.ActorFrame{} - -t[#t+1] = Def.Actor{ - CodeMessageCommand=function(self,params) - if params.Name == "AvatarShow" then - SCREENMAN:AddNewScreenToTop("ScreenAvatarSwitch"); - end; - end; -}; -t[#t+1] = LoadActor("../_frame"); -t[#t+1] = LoadActor("currentsort"); - - -t[#t+1] = LoadActor("../_cursor"); -t[#t+1] = LoadActor("../_halppls"); - -return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetSelectMusic decorations.lua b/BGAnimations/ScreenNetSelectMusic decorations.lua index 4b6e0cb7..baf9f534 100644 --- a/BGAnimations/ScreenNetSelectMusic decorations.lua +++ b/BGAnimations/ScreenNetSelectMusic decorations.lua @@ -1,150 +1,2 @@ -reset_needs_defective_field_for_all_players() -local t = Def.ActorFrame{} - -t[#t+1] = LoadActor("_chatbox") - -t[#t+1] = Def.Banner{ - InitCommand=function(self) - self:x(10):y(60):halign(0):valign(0) - end; - SetMessageCommand=function(self) - local top = SCREENMAN:GetTopScreen() - if top:GetName() == "ScreenSelectMusic" then - local song = GAMESTATE:GetCurrentSong() - local course = GAMESTATE:GetCurrentCourse() - local group = top:GetMusicWheel():GetSelectedSection() - if song then - self:LoadFromSong(song) - elseif course then - self:LoadFromCourse(song) - elseif group then - self:LoadFromSongGroup(group) - end; - elseif top:GetName() == "ScreenNetSelectMusic" then - local song = GAMESTATE:GetCurrentSong() - local course = GAMESTATE:GetCurrentCourse() - local group = top:GetChild("MusicWheel"):GetSelectedSection() - if song then - self:LoadFromSong(song) - elseif course then - self:LoadFromCourse(song) - elseif group then - self:LoadFromSongGroup(group) - end; - end; - self:scaletoclipped(capWideScale(get43size(384),384),capWideScale(get43size(120),120)) - end; - CurrentSongChangedMessageCommand=function(self) - self:queuecommand("Set") - end; -}; - - -t[#t+1] = Def.Quad{ - InitCommand=function(self) - self:xy(10,60+capWideScale(get43size(120),120)-capWideScale(get43size(10),10)):zoomto(capWideScale(get43size(384),384),capWideScale(get43size(20),20)):halign(0):diffuse(color("#000000")):diffusealpha(0.7) - end; -} - -t[#t+1] = LoadFont("Common Normal") .. { - Name="songTitle"; - InitCommand=function(self) - self:xy(15,60+capWideScale(get43size(120),120)-capWideScale(get43size(10),10)):visible(true):halign(0):zoom(capWideScale(get43size(0.45),0.45)):maxwidth(capWideScale(get43size(340),340)/capWideScale(get43size(0.45),0.45)) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - local song = GAMESTATE:GetCurrentSong() - if song ~= nil then - self:settext(song:GetDisplayMainTitle().." // "..song:GetDisplayArtist()) - else - self:settext("") - end - end; - CurrentSongChangedMessageCommand=function(self) - self:queuecommand("Set") - end; -}; - -t[#t+1] = LoadFont("Common Normal") .. { - Name="songLength"; - InitCommand=function(self) - self:xy(5+(capWideScale(get43size(384),384)),60+capWideScale(get43size(120),120)-capWideScale(get43size(10),10)):visible(true):halign(1):zoom(capWideScale(get43size(0.45),0.45)):maxwidth(capWideScale(get43size(360),360)/capWideScale(get43size(0.45),0.45)) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - local song = GAMESTATE:GetCurrentSong() - local seconds = 0 - if song ~= nil then - seconds = song:GetStepsSeconds() --song:MusicLengthSeconds() - self:settext(SecondsToMMSS(seconds)) - self:diffuse(getSongLengthColor(seconds)) - else - self:settext("") - end - end; - CurrentSongChangedMessageCommand=function(self) - self:queuecommand("Set") - end; -}; - -t[#t+1] = LoadFont("Common Normal") .. { - Name="songTitle"; - InitCommand=function(self) - self:xy(15,60+capWideScale(get43size(120),120)-capWideScale(get43size(10),10)):visible(true):halign(0):zoom(capWideScale(get43size(0.45),0.45)):maxwidth(capWideScale(get43size(340),340)/capWideScale(get43size(0.45),0.45)) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - local song = GAMESTATE:GetCurrentSong() - if song ~= nil then - self:settext(song:GetDisplayMainTitle().." // "..song:GetDisplayArtist()) - else - self:settext("") - end - end; - CurrentSongChangedMessageCommand=function(self) - self:queuecommand("Set") - end; -}; - -t[#t+1] = LoadFont("Common Normal")..{ - Name="StepsAndMeter"; - InitCommand = function(self) - self:xy(10+(capWideScale(get43size(384),384)),50) - self:zoom(0.5) - self:halign(1) - end; - SetCommand = function(self) - local pn = GAMESTATE:GetEnabledPlayers()[1] - local steps = GAMESTATE:GetCurrentSteps(pn) - if steps ~= nil then - - local diff = steps:GetDifficulty() - local stype = ToEnumShortString(steps:GetStepsType()):gsub("%_"," ") - local meter = steps:GetMeter() - local difftext - if diff == 'Difficulty_Edit' and IsUsingWideScreen() then - difftext = steps:GetDescription() - difftext = difftext == '' and getDifficulty(diff) or difftext - else - difftext = getDifficulty(diff) - end - if IsUsingWideScreen() then - self:settext(stype.." "..difftext.." "..meter) - else - self:settext(difftext.." "..meter) - end - self:diffuse(getDifficultyColor(GetCustomDifficulty(steps:GetStepsType(),steps:GetDifficulty()))) - end - end; - CurrentSongChangedMessageCommand = function(self) self:queuecommand('Set') end; - CurrentStepsP1ChangedMessageCommand = function(self) self:queuecommand('Set') end; - CurrentStepsP2ChangedMessageCommand = function(self) self:queuecommand('Set') end; - }; - +local t = LoadActor("ScreenSelectMusic decorations/net/default") return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetSelectMusic overlay.lua b/BGAnimations/ScreenNetSelectMusic overlay.lua new file mode 100644 index 00000000..545d464c --- /dev/null +++ b/BGAnimations/ScreenNetSelectMusic overlay.lua @@ -0,0 +1,3 @@ +local t = LoadActor("ScreenSelectMusic overlay/net/default") +t[#t+1] = LoadActor("_userlist") +return t \ No newline at end of file diff --git a/BGAnimations/ScreenNetSelectMusic underlay.lua b/BGAnimations/ScreenNetSelectMusic underlay.lua index dfcccb80..4250d647 100644 --- a/BGAnimations/ScreenNetSelectMusic underlay.lua +++ b/BGAnimations/ScreenNetSelectMusic underlay.lua @@ -1,6 +1,8 @@ local t = Def.ActorFrame{} t[#t+1] = LoadActor("_background") t[#t+1] = LoadActor("_songbg") -t[#t+1] = LoadActor("_particles"); +t[#t+1] = LoadActor("_particles") + +GHETTOGAMESTATE:resetGoalTable() -- refresh the goal table entering SSM return t \ No newline at end of file diff --git a/BGAnimations/ScreenPlayerOptions overlay.lua b/BGAnimations/ScreenPlayerOptions overlay.lua index 99bcedd8..071f4674 100644 --- a/BGAnimations/ScreenPlayerOptions overlay.lua +++ b/BGAnimations/ScreenPlayerOptions overlay.lua @@ -7,27 +7,21 @@ local borderWidth = 4 local t = Def.ActorFrame{ - Name="PlayerAvatar"; -}; + Name="PlayerAvatar", + BeginCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end +} local profileP1 -local profileP2 local profileNameP1 = "No Profile" local playCountP1 = 0 local playTimeP1 = 0 local noteCountP1 = 0 -local profileNameP2 = "No Profile" -local playCountP2 = 0 -local playTimeP2 = 0 -local noteCountP2 = 0 - - local AvatarXP1 = 100 local AvatarYP1 = 50 -local AvatarXP2 = SCREEN_WIDTH-130 -local AvatarYP2 = 50 local bpms = {} if GAMESTATE:GetCurrentSong() then @@ -41,7 +35,7 @@ t[#t+1] = Def.Actor{ BeginCommand=function(self) self:queuecommand("Set") - end; + end, SetCommand=function(self) if GAMESTATE:IsPlayerEnabled(PLAYER_1) then profileP1 = GetPlayerOrMachineProfile(PLAYER_1) @@ -59,131 +53,92 @@ t[#t+1] = Def.Actor{ playCountP1 = 0 playTimeP1 = 0 noteCountP1 = 0 - end; + end else profileNameP1 = "No Profile" playCountP1 = 0 playTimeP1 = 0 noteCountP1 = 0 - end; - end; - PlayerJoinedMessageCommand=function(self) - self:queuecommand("Set") - end; - PlayerUnjoinedMessageCommand=function(self) - self:queuecommand("Set") - end; -} - --- P2 Avatar -t[#t+1] = Def.Actor{ - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if GAMESTATE:IsPlayerEnabled(PLAYER_2) then - profileP2 = GetPlayerOrMachineProfile(PLAYER_2) - if profileP2 ~= nil then - if profileP2 == PROFILEMAN:GetMachineProfile() then - profileNameP2 = "Machine Profile" - else - profileNameP2 = profileP2:GetDisplayName() - end - playCountP2 = profileP2:GetTotalNumSongsPlayed() - playTimeP2 = profileP2:GetTotalSessionSeconds() - noteCountP2 = profileP2:GetTotalTapsAndHolds() - else - profileNameP2 = "No Profile" - playCountP2 = 0 - playTimeP2 = 0 - noteCountP2 = 0 - end; - else - profileNameP2 = "No Profile" - playCountP2 = 0 - playTimeP2 = 0 - noteCountP2 = 0 - end; - end; + end + end, PlayerJoinedMessageCommand=function(self) self:queuecommand("Set") - end; + end, PlayerUnjoinedMessageCommand=function(self) self:queuecommand("Set") - end; + end } - t[#t+1] = Def.ActorFrame{ - Name="Avatar"..PLAYER_1; + Name="Avatar"..PLAYER_1, BeginCommand=function(self) self:queuecommand("Set") - end; + end, SetCommand=function(self) if profileP1 == nil then self:visible(false) else self:visible(true) - end; - end; + end + end, PlayerJoinedMessageCommand=function(self) self:queuecommand("Set") - end; + end, PlayerUnjoinedMessageCommand=function(self) self:queuecommand("Set") - end; + end, Def.Sprite { - Name="Image"; + Name="Image", InitCommand=function(self) self:visible(true):halign(0):valign(0):xy(AvatarXP1,AvatarYP1) - end; + end, BeginCommand=function(self) self:queuecommand("ModifyAvatar") - end; + end, PlayerJoinedMessageCommand=function(self) self:queuecommand("ModifyAvatar") - end; + end, PlayerUnjoinedMessageCommand=function(self) self:queuecommand("ModifyAvatar") - end; + end, ModifyAvatarCommand=function(self) - self:finishtweening(); - self:LoadBackground(PROFILEMAN:GetAvatarPath(PLAYER_1)); + self:finishtweening() + self:LoadBackground(assetFolders.avatar .. findAvatar(PROFILEMAN:GetProfile(PLAYER_1):GetGUID())) self:zoomto(30,30) - end; - }; + end + }, LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(AvatarXP1+33,AvatarYP1+6):halign(0):zoom(0.45) - end; + end, BeginCommand=function(self) self:queuecommand("Set") - end; + end, SetCommand=function(self) self:settext(profileNameP1.."'s Scroll Speed:") - end; + end, PlayerJoinedMessageCommand=function(self) self:queuecommand("Set") - end; + end, PlayerUnjoinedMessageCommand=function(self) self:queuecommand("Set") - end; - }; + end + }, LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(AvatarXP1+33,AvatarYP1+19):halign(0):zoom(0.40) - end; + end, BeginCommand=function(self) local speed, mode= GetSpeedModeAndValueFromPoptions(PLAYER_1) self:playcommand("SpeedChoiceChanged", {pn= PLAYER_1, mode= mode, speed= speed}) - end; + end, PlayerJoinedMessageCommand=function(self) self:queuecommand("Set") - end; + end, PlayerUnjoinedMessageCommand=function(self) self:queuecommand("Set") - end; + end, SpeedChoiceChangedMessageCommand=function(self,param) if param.pn == PLAYER_1 then local rate = GAMESTATE:GetSongOptionsObject('ModsLevel_Current'):MusicRate() or 1 @@ -210,108 +165,7 @@ t[#t+1] = Def.ActorFrame{ end self:settext(text) end - end; - } -} - --- P2 Avatar -t[#t+1] = Def.ActorFrame{ - Name="Avatar"..PLAYER_2; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if profileP2 == nil then - self:visible(false) - else - self:visible(true) - end; - end; - PlayerJoinedMessageCommand=function(self) - self:queuecommand("Set") - end; - PlayerUnjoinedMessageCommand=function(self) - self:queuecommand("Set") - end; - - Def.Sprite { - Name="Image"; - InitCommand=function(self) - self:visible(true):halign(0):valign(0):xy(AvatarXP2,AvatarYP2) - end; - BeginCommand=function(self) - self:queuecommand("ModifyAvatar") - end; - PlayerJoinedMessageCommand=function(self) - self:queuecommand("ModifyAvatar") - end; - PlayerUnjoinedMessageCommand=function(self) - self:queuecommand("ModifyAvatar") - end; - ModifyAvatarCommand=function(self) - self:finishtweening(); - self:LoadBackground(PROFILEMAN:GetAvatarPath(PLAYER_2)); - self:zoomto(30,30) - end; - }; - LoadFont("Common Normal") .. { - InitCommand=function(self) - self:xy(AvatarXP2-3,AvatarYP2+7):halign(1):zoom(0.45) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - self:settext(profileNameP2.."'s Scroll Speed:") - end; - PlayerJoinedMessageCommand=function(self) - self:queuecommand("Set") - end; - PlayerUnjoinedMessageCommand=function(self) - self:queuecommand("Set") - end; - }; - LoadFont("Common Normal") .. { - InitCommand=function(self) - self:xy(AvatarXP2-3,AvatarYP2+19):halign(1):zoom(0.45) - end; - BeginCommand=function(self) - local speed, mode= GetSpeedModeAndValueFromPoptions(PLAYER_2) - self:playcommand("SpeedChoiceChanged", {pn= PLAYER_2, mode= mode, speed= speed}) - end; - PlayerJoinedMessageCommand=function(self) - self:queuecommand("Set") - end; - PlayerUnjoinedMessageCommand=function(self) - self:queuecommand("Set") - end; - SpeedChoiceChangedMessageCommand=function(self,param) - if param.pn == PLAYER_2 then - local text = "" - local rate = GAMESTATE:GetSongOptionsObject('ModsLevel_Current'):MusicRate() or 1 - if param.mode == "x" then - if not bpms[1] then - text = "??? - ???" - elseif bpms[1] == bpms[2] then - text = math.round(bpms[1]*rate*param.speed/100) - else - text = string.format("%d - %d",math.round(bpms[1]*rate*param.speed/100),math.round(bpms[2]*rate*param.speed/100)) - end - elseif param.mode == "C" then - text = param.speed - else - if not bpms[1] then - text = "??? - "..param.speed - elseif bpms[1] == bpms[2] then - text = param.speed - else - local factor = param.speed/bpms[2] - text = string.format("%d - %d",math.round(bpms[1]*factor),param.speed) - end - end - self:settext(text) - end - end; + end } } diff --git a/BGAnimations/ScreenPlayerProfile decorations/avatar.lua b/BGAnimations/ScreenPlayerProfile decorations/avatar.lua index 2f986ba6..d4e81be1 100644 --- a/BGAnimations/ScreenPlayerProfile decorations/avatar.lua +++ b/BGAnimations/ScreenPlayerProfile decorations/avatar.lua @@ -16,45 +16,45 @@ t[#t+1] = Def.Quad{ InitCommand = function(self) self:zoomto(avatarHeight+avatarBorder*2,avatarWidth+avatarBorder*2) self:diffuse(getBorderColor()) - end; + end } t[#t+1] = Def.Quad{ InitCommand = function(self) self:zoomto(avatarHeight+avatarBorder*2,avatarWidth+avatarBorder*2) self:diffusealpha(0.8) - end; + end, BeginCommand = function(self) self:diffuseramp() self:effectcolor2(color("1,1,1,0.6")) self:effectcolor1(color("1,1,1,0")) self:effecttiming(2,1,0,0) - end; + end } t[#t+1] = quadButton(3) .. { InitCommand = function(self) self:zoomto(avatarHeight+avatarBorder*2,avatarWidth+avatarBorder*2) self:visible(false) - end; + end, TopPressedCommand = function(self, params) if params.input == "DeviceButton_left mouse button" then SCREENMAN:AddNewScreenToTop("ScreenSelectAvatar") end - end; + end } -- Avatar t[#t+1] = Def.Sprite { - InitCommand = function (self) self:playcommand("ModifyAvatar") end; - PlayerJoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end; - PlayerUnjoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end; - AvatarChangedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end; + InitCommand = function (self) self:playcommand("ModifyAvatar") end, + PlayerJoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end, + PlayerUnjoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end, + AvatarChangedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end, ModifyAvatarCommand = function(self) self:visible(true) - self:LoadBackground(PROFILEMAN:GetAvatarPath(pn)); + self:LoadBackground(assetFolders.avatar .. findAvatar(profile:GetGUID())) self:zoomto(avatarHeight,avatarWidth) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenPlayerProfile decorations/default.lua b/BGAnimations/ScreenPlayerProfile decorations/default.lua index 8a873190..f106fb78 100644 --- a/BGAnimations/ScreenPlayerProfile decorations/default.lua +++ b/BGAnimations/ScreenPlayerProfile decorations/default.lua @@ -4,21 +4,21 @@ t[#t+1] = LoadActor("profilecard") .. { InitCommand = function(self) self:xy(10,80) self:delayedFadeIn(0) - end; + end } t[#t+1] = LoadActor("ssrbreakdown") .. { InitCommand = function(self) self:xy(160,295) self:delayedFadeIn(1) - end; + end } t[#t+1] = LoadActor("infobox") .. { InitCommand = function(self) self:xy(320,30) self:delayedFadeIn(2) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenPlayerProfile decorations/expbar.lua b/BGAnimations/ScreenPlayerProfile decorations/expbar.lua index 98982ce7..7a78dd1f 100644 --- a/BGAnimations/ScreenPlayerProfile decorations/expbar.lua +++ b/BGAnimations/ScreenPlayerProfile decorations/expbar.lua @@ -19,12 +19,12 @@ t[#t+1] = LoadFont("Common Normal")..{ self:halign(1) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:queuecommand('Set') - end; + end, SetCommand = function(self) if profile ~= nil then self:settextf("Lv.%d (%d/%d)",level, currentExp, nextExp) end - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -34,25 +34,29 @@ t[#t+1] = LoadFont("Common Normal")..{ self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:playcommand('Set') - end; + end, LoginMessageCommand = function(self) self:playcommand('Set') - end; + end, LogOutMessageCommand = function(self) self:playcommand('Set') - end; + end, OnlineUpdateMessageCommand = function(self) self:playcommand('Set') - end; + end, + + OnlineTogglePressedMessageCommand = function(self) + self:playcommand('Set') + end, SetCommand = function(self) local rating = 0 local rank = 0 - if DLMAN:IsLoggedIn() then + if GHETTOGAMESTATE:getOnlineStatus() == "Online" and DLMAN:IsLoggedIn() then rank = DLMAN:GetSkillsetRank("Overall") rating = DLMAN:GetSkillsetRating("Overall") @@ -67,7 +71,7 @@ t[#t+1] = LoadFont("Common Normal")..{ end self:AddAttribute(#"Skill Rating:", {Length = -1, Zoom =0.3 ,Diffuse = getMSDColor(rating)}) - end; + end } t[#t+1] = Def.Quad{ @@ -83,7 +87,7 @@ t[#t+1] = Def.Quad{ self:zoomto(0, barHeight-2) self:diffuse(color(colorConfig:get_data().main.highlight)) self:queuecommand('Set') - end; + end, SetCommand = function (self) if profile ~= nil then self:easeOut(1) diff --git a/BGAnimations/ScreenPlayerProfile decorations/infobox.lua b/BGAnimations/ScreenPlayerProfile decorations/infobox.lua index 28ddb901..6b48c693 100644 --- a/BGAnimations/ScreenPlayerProfile decorations/infobox.lua +++ b/BGAnimations/ScreenPlayerProfile decorations/infobox.lua @@ -44,7 +44,7 @@ t[#t+1] = LoadFont("Common Bold")..{ self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Top Scores") - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -54,10 +54,19 @@ t[#t+1] = LoadFont("Common Normal")..{ self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settextf("Sorted by: %s",SkillSets[1]) - end; + end, UpdateRankingMessageCommand = function(self, params) self:settextf("Sorted by: %s",params.SSRType) - end; + end, + OnlineTogglePressedMessageCommand = function(self) + self:settext("Sorted by: Overall") + end, + LoginMessageCommand = function(self) + self:settext("Sorted by: Overall") + end, + LogOutMessageCommand = function(self) + self:settext("Sorted by: Overall") + end, DisplaySongMessageCommand = function(self, params) self:visible(false) end @@ -69,7 +78,7 @@ local function scoreSSRTypes(i) local t = Def.ActorFrame{ InitCommand = function(self) self:playcommand("Tween") - end; + end, TweenCommand = function(self) self:finishtweening() self:xy(scoreSSRItemX, scoreSSRItemY + (i-1)*(scoreSSRItemHeight+scoreSSRItemYSpacing)-10) @@ -78,7 +87,7 @@ local function scoreSSRTypes(i) self:easeOut(0.5) self:diffusealpha(1) self:xy(scoreSSRItemX, scoreSSRItemY + (i-1)*(scoreSSRItemHeight+scoreSSRItemYSpacing)) - end; + end, DisplaySongMessageCommand = function(self, params) self:visible(false) self:y(SCREEN_HEIGHT*10) @@ -89,14 +98,14 @@ local function scoreSSRTypes(i) InitCommand = function(self) self:diffusealpha(0.2) self:zoomto(scoreSSRItemWidth, scoreSSRItemHeight) - end; + end, TopPressedCommand = function(self) self:finishtweening() self:diffusealpha(0.4) self:smooth(0.3) self:diffusealpha(0.2) MESSAGEMAN:Broadcast("UpdateRanking",{SSRType = SkillSets[i]}) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -105,7 +114,7 @@ local function scoreSSRTypes(i) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext(SkillSets[i]) self:zoom(0.4) - end; + end } return t @@ -123,11 +132,12 @@ local function scoreListItem(i) local chartKey = ths:GetChartKey() local steps = SONGMAN:GetStepsByChartKey(chartKey) local song = SONGMAN:GetSongByChartKey(chartKey) + local onlineScore = DLMAN:GetTopSkillsetScore(i, "Overall") local t = Def.ActorFrame{ InitCommand = function(self) self:playcommand("Tween") - end; + end, TweenCommand = function(self) self:finishtweening() self:xy(scoreItemX, scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)-10) @@ -136,17 +146,65 @@ local function scoreListItem(i) self:easeOut(1) self:diffusealpha(1) self:xy(scoreItemX, scoreItemY + (i-1)*(scoreItemHeight+scoreItemYSpacing)) - end; + end, UpdateRankingMessageCommand = function(self, params) - SCOREMAN:SortSSRs(params.SSRType) - skillset = params.SSRType - ths = SCOREMAN:GetTopSSRHighScore(i, params.SSRType) + if GHETTOGAMESTATE:getOnlineStatus() == "Online" then + onlineScore = DLMAN:GetTopSkillsetScore(i, params.SSRType) + if not onlineScore then + self:visible(false) + else + self:visible(true) + end + else + SCOREMAN:SortSSRs(params.SSRType) + skillset = params.SSRType + ths = SCOREMAN:GetTopSSRHighScore(i, params.SSRType) + chartKey = ths:GetChartKey() + song = SONGMAN:GetSongByChartKey(chartKey) + steps = SONGMAN:GetStepsByChartKey(chartKey) + self:visible(true) + end + self:playcommand("Tween") + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + end, + LoginMessageCommand = function(self) + GHETTOGAMESTATE:setOnlineStatus("Online") + self:visible(false) + self:playcommand("Tween") + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + end, + LogOutMessageCommand = function(self) + GHETTOGAMESTATE:setOnlineStatus("Local") + SCOREMAN:SortSSRs("Overall") + skillset = "Overall" + ths = SCOREMAN:GetTopSSRHighScore(i, "Overall") chartKey = ths:GetChartKey() song = SONGMAN:GetSongByChartKey(chartKey) steps = SONGMAN:GetStepsByChartKey(chartKey) + self:visible(true) self:playcommand("Tween") self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) - end; + end, + OnlineTogglePressedMessageCommand = function(self) + if GHETTOGAMESTATE:getOnlineStatus() == "Online" then + onlineScore = DLMAN:GetTopSkillsetScore(i, SkillSets[1]) + if not onlineScore then + self:visible(false) + else + self:visible(true) + end + else + SCOREMAN:SortSSRs("Overall") + skillset = "Overall" + ths = SCOREMAN:GetTopSSRHighScore(i, "Overall") + chartKey = ths:GetChartKey() + song = SONGMAN:GetSongByChartKey(chartKey) + steps = SONGMAN:GetStepsByChartKey(chartKey) + self:visible(true) + end + self:playcommand("Tween") + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + end, DisplaySongMessageCommand = function(self, params) self:visible(false) self:y(SCREEN_HEIGHT*10) -- Send it off screen so buttons don't overlap. @@ -158,16 +216,21 @@ local function scoreListItem(i) self:halign(0) self:diffusealpha(0.2) self:zoomto(scoreItemWidth, scoreItemHeight) - end; - TopPressedCommand = function(self) + end, + TopPressedCommand = function(self, params) self:finishtweening() self:diffusealpha(0.4) self:smooth(0.3) self:diffusealpha(0.2) - --MESSAGEMAN:Broadcast("DisplaySong",{score = ths}) - SCREENMAN:GetTopScreen():Cancel() - MESSAGEMAN:Broadcast("MoveMusicWheelToSong",{song = song}) - end; + if params.input == "DeviceButton_right mouse button" then + ths:ToggleEtternaValidation() + MESSAGEMAN:Broadcast("UpdateRanking", {SSRType = skillset}) + elseif params.input == "DeviceButton_left mouse button" then + --MESSAGEMAN:Broadcast("DisplaySong",{score = ths}) + SCREENMAN:GetTopScreen():Cancel() + MESSAGEMAN:Broadcast("MoveMusicWheelToSong",{song = song}) + end + end, SetCommand = function(self) if ths:GetEtternaValid() then self:diffuse(color("#FFFFFF")) @@ -175,7 +238,7 @@ local function scoreListItem(i) self:diffuse(color(colorConfig:get_data().clearType.ClearType_Invalid)) end self:diffusealpha(0.2) - end; + end } t[#t+1] = Def.Quad{ @@ -186,10 +249,14 @@ local function scoreListItem(i) self:xy(30, 0) self:zoomto(2, scoreItemHeight) self:playcommand("Set") - end; + end, SetCommand = function(self) - self:diffuse(color(colorConfig:get_data().difficulty[steps:GetDifficulty()])) - end; + if GHETTOGAMESTATE:getOnlineStatus() == "Online" then + self:diffuse(color("#AAAAAA")) + else + self:diffuse(color(colorConfig:get_data().difficulty[steps:GetDifficulty()])) + end + end } @@ -199,12 +266,19 @@ local function scoreListItem(i) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) self:playcommand("Set") - end; + end, SetCommand = function(self) - local rating = ths:GetSkillsetSSR(skillset) - self:settextf("%0.2f", rating) - self:diffuse(getMSDColor(rating)) - end; + if GHETTOGAMESTATE:getOnlineStatus() == "Online" then + if onlineScore then + self:settextf("%0.2f", onlineScore.ssr) + self:diffuse(getMSDColor(onlineScore.ssr)) + end + else + local rating = ths:GetSkillsetSSR(skillset) + self:settextf("%0.2f", rating) + self:diffuse(getMSDColor(rating)) + end + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -214,9 +288,15 @@ local function scoreListItem(i) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) self:playcommand("Set") - end; + end, SetCommand = function(self) - self:settextf("%s (x%0.2f)",song:GetMainTitle(),ths:GetMusicRate()) + if GHETTOGAMESTATE:getOnlineStatus() == "Online" then + if onlineScore then + self:settextf("%s (x%0.2f)", onlineScore.songName, onlineScore.rate) + end + else + self:settextf("%s (x%0.2f)",song:GetMainTitle(),ths:GetMusicRate()) + end end } @@ -227,9 +307,13 @@ local function scoreListItem(i) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) self:playcommand("Set") - end; + end, SetCommand = function(self) - self:settextf("// %s",song:GetDisplayArtist()) + if GHETTOGAMESTATE:getOnlineStatus() ~= "Online" then + self:settextf("// %s",song:GetDisplayArtist()) + else + self:settext("") + end end } @@ -240,14 +324,14 @@ local function scoreListItem(i) self:wag() self:diffuse(Color.Yellow) self:playcommand("Set") - end; + end, SetCommand = function(self,params) - if song:IsFavorited() then + if song:IsFavorited() and GHETTOGAMESTATE:getOnlineStatus() ~= "Online" then self:visible(true) else self:visible(false) end - end; + end } return t @@ -268,7 +352,7 @@ local function songDisplay() InitCommand = function(self) self:visible(false) self:xy(songDisplayX, SCREEN_HEIGHT*10) - end; + end, DisplaySongMessageCommand = function(self, params) self:xy(songDisplayX, songDisplayY) self:visible(true) @@ -277,8 +361,8 @@ local function songDisplay() steps = SONGMAN:GetStepsByChartKey(chartKey) song = SONGMAN:GetSongByChartKey(chartKey) - self:RunCommandsOnChildren(cmd(queuecommand, "Set")) - end; + self:RunCommandsOnChildren(function(self) self:queuecommand("Set") end) + end } t[#t+1] = quadButton(6) .. { @@ -286,7 +370,7 @@ local function songDisplay() self:halign(0) self:diffusealpha(0.2) self:zoomto(songDisplayWidth, songDisplayHeight) - end; + end, TopPressedCommand = function(self) self:finishtweening() self:diffusealpha(0.4) @@ -294,9 +378,9 @@ local function songDisplay() self:diffusealpha(0.2) SCREENMAN:GetTopScreen():Cancel() MESSAGEMAN:Broadcast("MoveMusicWheelToSong",{song = song}) - end; + end, SetCommand = function(self) - end; + end } t[#t+1] = Def.Quad{ @@ -311,7 +395,7 @@ local function songDisplay() t[#t+1] = Def.Sprite { SetCommand = function(self) if song:HasJacket() then - self:visible(true); + self:visible(true) self:Load(song:GetJacketPath()) elseif song:HasBackground() then self:visible(true) @@ -321,7 +405,7 @@ local function songDisplay() end self:diffusealpha(0.8) self:scaletofit(10, -songDisplayHeight/2, (songDisplayHeight-20)/3*4+10 , songDisplayHeight/2) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -331,7 +415,7 @@ local function songDisplay() self:diffusealpha(0.2) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.5) - end; + end, SetCommand = function(self) local diff = getDifficulty(steps:GetDifficulty()) local stype = ToEnumShortString(steps:GetStepsType()):gsub("%_"," ") @@ -345,7 +429,7 @@ local function songDisplay() self:settext(diff.." "..meter) end self:diffuse(getDifficultyColor(GetCustomDifficulty(steps:GetStepsType(),steps:GetDifficulty()))) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -355,23 +439,23 @@ local function songDisplay() self:diffusealpha(0.2) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) - end; + end, SetCommand = function(self) local length = song:GetStepsSeconds() local notecount = steps:GetRadarValues(pn):GetValue("RadarCategory_Notes") self:settext(string.format("%0.2f %s",notecount/length,THEME:GetString("ScreenSelectMusic","SimfileInfoAvgNPS"))) self:diffuse(Saturation(getDifficultyColor(GetCustomDifficulty(steps:GetStepsType(),steps:GetDifficulty())),0.3)) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ - Name="MSDAvailability"; + Name="MSDAvailability", InitCommand = function(self) self:xy(songDisplayWidth-5,-songDisplayHeight/2+30) self:zoom(0.3) self:halign(1) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - end; + end, SetCommand = function(self) local meter = math.floor(steps:GetMSD(getCurRateValue(),1)) if meter == 0 then @@ -381,61 +465,61 @@ local function songDisplay() self:settext("MSD") self:diffuse(color(colorConfig:get_data().main.enabled)) end - end; - }; + end + } t[#t+1] = LoadFont("Common Normal")..{ - Name = "Song Title"; + Name = "Song Title", InitCommand = function(self) self:xy(songDisplayHeight+40,-15) self:zoom(0.6) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - end; + end, SetCommand = function(self) self:settext(song:GetDisplayMainTitle()) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:GetParent():GetChild("Song Length"):x(songDisplayHeight+40+(self:GetWidth()*0.60)) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ - Name = "Song Length"; + Name = "Song Length", InitCommand = function(self) self:xy(songDisplayHeight+40,-18) self:zoom(0.3) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - end; + end, SetCommand = function(self) local length = song:GetStepsSeconds() self:settext(string.format("%s",SecondsToMSS(length))) self:diffuse(getSongLengthColor(length)) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ - Name = "Song SubTitle"; + Name = "Song SubTitle", InitCommand = function(self) self:xy(songDisplayHeight+40,0) self:zoom(0.4) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - end; + end, SetCommand = function(self) self:settext(song:GetDisplaySubTitle()) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ - Name = "Song Artist"; + Name = "Song Artist", InitCommand = function(self) self:xy(songDisplayHeight+40,13) self:zoom(0.4) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - end; + end, SetCommand = function(self) self:settext(song:GetDisplayArtist()) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) @@ -444,7 +528,7 @@ local function songDisplay() else self:y(13) end - end; + end } t[#t+1] = LoadActor(THEME:GetPathG("", "round_star")) .. { @@ -453,14 +537,14 @@ local function songDisplay() self:zoom(0.3) self:wag() self:diffuse(Color.Yellow) - end; + end, SetCommand = function(self) if song:IsFavorited() then self:visible(true) else self:visible(false) end - end; + end } return t diff --git a/BGAnimations/ScreenPlayerProfile decorations/profilecard.lua b/BGAnimations/ScreenPlayerProfile decorations/profilecard.lua index 2fd4c198..fb00890a 100644 --- a/BGAnimations/ScreenPlayerProfile decorations/profilecard.lua +++ b/BGAnimations/ScreenPlayerProfile decorations/profilecard.lua @@ -1,5 +1,6 @@ local pn = GAMESTATE:GetEnabledPlayers()[1] local profile = PROFILEMAN:GetProfile(pn) +local onlineStatus = GHETTOGAMESTATE:getOnlineStatus() local t = Def.ActorFrame{ @@ -16,21 +17,59 @@ t[#t+1] = Def.Quad{ t[#t+1] = LoadActor("avatar") .. { InitCommand = function(self) self:xy(50,0) - end; + end } t[#t+1] = LoadActor("expbar") .. { InitCommand = function(self) self:xy(100,5) - end; + end } +local function toggleOnlineStatus(given) + if DLMAN:IsLoggedIn() then + if given ~= nil then + GHETTOGAMESTATE:setOnlineStatus(given) + else + GHETTOGAMESTATE:setOnlineStatus() + end + onlineStatus = GHETTOGAMESTATE:getOnlineStatus() + else + GHETTOGAMESTATE:setOnlineStatus("Local") + onlineStatus = "Local" + end +end + t[#t+1] = quadButton(3)..{ InitCommand = function (self) self:xy(145,30) self:zoomto(90,20) - self:diffuse(color(colorConfig:get_data().main.disabled)):diffusealpha(0.8) + self:diffuse(color(colorConfig:get_data().main.disabled)) + if DLMAN:IsLoggedIn() then + self:diffusealpha(0.8) + else + self:diffusealpha(0.2) + end + end, + TopPressedCommand = function(self) + if DLMAN:IsLoggedIn() then + self:finishtweening() + self:diffusealpha(1) + self:smooth(0.3) + self:diffusealpha(0.8) + toggleOnlineStatus() + MESSAGEMAN:Broadcast("OnlineTogglePressed") + end + end, + LoginMessageCommand = function(self) + self:diffusealpha(0.8) + end, + LoginFailedMessageCommand = function(self) + --self:diffusealpha(0.8) + end, + LogOutMessageCommand = function(self) + self:diffusealpha(0.2) end } @@ -39,12 +78,28 @@ t[#t+1] = LoadFont("Common Bold")..{ InitCommand = function(self) self:xy(145,30) self:zoom(0.4) - self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.4) + self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) + if not DLMAN:IsLoggedIn() then + self:diffusealpha(0.4) + end self:queuecommand('Set') - end; + end, SetCommand = function(self) - self:settext("Update") - end; + self:settextf("%s", onlineStatus) + end, + LogOutMessageCommand = function(self) + toggleOnlineStatus("Local") + self:diffusealpha(0.4) + self:queuecommand("Set") + end, + LoginMessageCommand = function(self) + self:diffusealpha(1) + toggleOnlineStatus("Online") + self:queuecommand("Set") + end, + OnlineTogglePressedMessageCommand = function(self) + self:queuecommand("Set") + end } t[#t+1] = quadButton(3)..{ @@ -57,7 +112,7 @@ t[#t+1] = quadButton(3)..{ else self:diffuse(color(colorConfig:get_data().main.enabled)):diffusealpha(0.8) end - end; + end, -- Login StartLoginCommand = function(self) @@ -67,24 +122,24 @@ t[#t+1] = quadButton(3)..{ DLMAN:Login(user, pass) end - easyInputStringWithFunction("Password:", 50, true, password) - easyInputStringWithFunction("Username:",50, false, username) - end; + easyInputStringWithFunction("Password:", 255, true, password) + easyInputStringWithFunction("Username:", 255, false, username) + end, -- Save config upon successful login LoginMessageCommand = function(self) self:diffuse(color(colorConfig:get_data().main.negative)):diffusealpha(0.8) - playerConfig:get_data(pn_to_profile_slot(pn)).Username = user - playerConfig:get_data(pn_to_profile_slot(pn)).Password = pass + playerConfig:get_data(pn_to_profile_slot(pn)).Username = DLMAN:GetUsername() + playerConfig:get_data(pn_to_profile_slot(pn)).Password = DLMAN:GetToken() playerConfig:set_dirty(pn_to_profile_slot(pn)) playerConfig:save(pn_to_profile_slot(pn)) SCREENMAN:SystemMessage("Login Successful!") - end; + end, -- Do nothing on failed login LoginFailedMessageCommand = function(self) SCREENMAN:SystemMessage("Login Failed!") - end; + end, -- delete config upon logout StartLogoutCommand = function(self) @@ -93,7 +148,7 @@ t[#t+1] = quadButton(3)..{ playerConfig:set_dirty(pn_to_profile_slot(pn)) playerConfig:save(pn_to_profile_slot(pn)) DLMAN:Logout() - end; + end, LogOutMessageCommand=function(self) self:diffuse(color(colorConfig:get_data().main.enabled)):diffusealpha(0.8) @@ -111,7 +166,7 @@ t[#t+1] = quadButton(3)..{ self:diffusealpha(1) self:smooth(0.3) self:diffusealpha(0.8) - end; + end } t[#t+1] = LoadFont("Common Bold")..{ @@ -124,11 +179,11 @@ t[#t+1] = LoadFont("Common Bold")..{ else self:settext("Login") end - end; + end, LoginMessageCommand = function(self) self:settext("Logout") - end; + end, LogOutMessageCommand=function(self) self:settext("Login") @@ -145,9 +200,9 @@ t[#t+1] = LoadFont("Common BLarge")..{ self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:queuecommand('Set') - end; - LoginMessageCommand = function(self) self:queuecommand('Set') end; - LogOutMessageCommand = function(self) self:queuecommand('Set') end; + end, + LoginMessageCommand = function(self) self:queuecommand('Set') end, + LogOutMessageCommand = function(self) self:queuecommand('Set') end, SetCommand = function(self) local text = "" @@ -159,7 +214,7 @@ t[#t+1] = LoadFont("Common BLarge")..{ end self:settext(text) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenPlayerProfile decorations/ssrbreakdown.lua b/BGAnimations/ScreenPlayerProfile decorations/ssrbreakdown.lua index 49bf5009..acf96091 100644 --- a/BGAnimations/ScreenPlayerProfile decorations/ssrbreakdown.lua +++ b/BGAnimations/ScreenPlayerProfile decorations/ssrbreakdown.lua @@ -38,7 +38,7 @@ t[#t+1] = LoadFont("Common Bold")..{ self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Skill Rating Breakdown") - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -48,21 +48,24 @@ t[#t+1] = LoadFont("Common Normal")..{ self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:queuecommand("Set") - end; + end, SetCommand = function(self) - if DLMAN:IsLoggedIn() then + if GHETTOGAMESTATE:getOnlineStatus() == "Online" then self:settext("Using server values") else self:settext("Using client values") end - end; + end, OnlineUpdateMessageCommand = function(self) self:queuecommand("Set") - end; + end, LogOutMessageCommand = function(self) self:queuecommand("Set") - end; + end, + OnlineTogglePressedMessageCommand = function(self) + self:queuecommand("Set") + end } local sepAngle = 360/#SkillSets-1 @@ -77,10 +80,10 @@ local function makeSSRPoints(i) self:zoom(0.3) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:queuecommand("Set") - end; + end, SetCommand = function(self) local SSR = 0 - if DLMAN:IsLoggedIn() then + if GHETTOGAMESTATE:getOnlineStatus() == "Online" then SSR = DLMAN:GetSkillsetRating(SkillSets[i]) else SSR = profile:GetPlayerSkillsetRating(SkillSets[i]) @@ -88,13 +91,22 @@ local function makeSSRPoints(i) self:settextf("%s\n%0.2f",SkillSets[i], SSR) self:AddAttribute(#SkillSets[i], {Length = -1, Diffuse = getMSDColor(SSR)}) - end; + end, + OnlineTogglePressedMessageCommand = function(self) + self:queuecommand("Set") + end, + LogOutMessageCommand = function(self) + self:queuecommand("Set") + end, + OnlineUpdateMessageCommand = function(self) + self:queuecommand("Set") + end } end t[#t+1] = Def.ActorMultiVertex{ - Name= "SSR_MAX_Graph"; + Name= "SSR_MAX_Graph", InitCommand = function(self) local x,y for i=1, #SkillSets do @@ -110,40 +122,43 @@ t[#t+1] = Def.ActorMultiVertex{ self:SetDrawState{First= 1, Num= -1} self:SetDrawState{Mode="DrawMode_QuadStrip"} self:playcommand("Set") - end; + end, SetCommand = function(self) self:diffusealpha(0.2) self:SetVertices(maxVerts) self:SetDrawState{First= 1, Num= -1} - end; + end, OnlineUpdateMessageCommand = function(self) self:queuecommand("Set") - end; + end, LogOutMessageCommand = function(self) self:queuecommand("Set") - end; + end } t[#t+1] = Def.ActorMultiVertex{ - Name= "SSR_Graph"; + Name= "SSR_Graph", InitCommand = function(self) self:diffusealpha(0.5) self:SetDrawState{Mode="DrawMode_QuadStrip"} self:queuecommand("Set") - end; + end, OnlineUpdateMessageCommand = function(self) self:queuecommand("Set") - end; + end, LogOutMessageCommand = function(self) self:queuecommand("Set") - end; + end, + OnlineTogglePressedMessageCommand = function(self) + self:queuecommand("Set") + end, SetCommand = function(self) verts = {} local x,y for i=1, #SkillSets do local SSR = 0 x,y = getPointOffset(circleRadius,sepAngle*(i-1)-90) - if DLMAN:IsLoggedIn() then + if GHETTOGAMESTATE:getOnlineStatus() == "Online" then SSR = DLMAN:GetSkillsetRating(SkillSets[i]) else SSR = profile:GetPlayerSkillsetRating(SkillSets[i]) @@ -160,7 +175,7 @@ t[#t+1] = Def.ActorMultiVertex{ self:easeOut(1) self:SetVertices(verts) self:SetDrawState{First= 1, Num= -1} - end; + end } diff --git a/BGAnimations/ScreenPlayerProfile overlay/default.lua b/BGAnimations/ScreenPlayerProfile overlay/default.lua index ea06278d..80042985 100644 --- a/BGAnimations/ScreenPlayerProfile overlay/default.lua +++ b/BGAnimations/ScreenPlayerProfile overlay/default.lua @@ -1,10 +1,11 @@ - - local function input(event) - if event.type == "InputEventType_Release" then + if event.type == "InputEventType_FirstPress" then if event.button == "Back" or event.button == "Start" then SCREENMAN:GetTopScreen():Cancel() end + if tonumber(event.char) == 1 then + SCREENMAN:AddNewScreenToTop("ScreenGoalManager") + end end return false @@ -12,29 +13,49 @@ local function input(event) end local top +local sentSong local t = Def.ActorFrame { OnCommand = function(self) top = SCREENMAN:GetTopScreen() top:AddInputCallback(input) - end; + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end, + TriggerExitFromPSMessageCommand = function(self, params) + self:sleep(0.05) + sentSong = params.song + self:queuecommand("DelayedExitPS") + end, + DelayedExitPSCommand = function(self) + SCREENMAN:GetTopScreen():Cancel() + MESSAGEMAN:Broadcast("MoveMusicWheelToSong",{song = sentSong}) + end } t[#t+1] = LoadActor("../_mouse") t[#t+1] = LoadActor("../_frame") -local tab = TAB:new({"Scores", "Stats", "Other"}) +local tab = TAB:new({"Goals"}) t[#t+1] = tab:makeTabActors() .. { OnCommand = function(self) - self:y(SCREEN_HEIGHT+tab.height/2) - self:easeOut(0.5) - self:y(SCREEN_HEIGHT-tab.height/2) - end; + if IsNetSMOnline() and IsSMOnlineLoggedIn(PLAYER_1) and NSMAN:IsETTP() then + self:y(SCREEN_HEIGHT+tab.height/2 - 17) + self:easeOut(0.5) + self:y(SCREEN_HEIGHT-tab.height/2 - 17) + else + self:y(SCREEN_HEIGHT+tab.height/2) + self:easeOut(0.5) + self:y(SCREEN_HEIGHT-tab.height/2) + end + end, OffCommand = function(self) self:y(SCREEN_HEIGHT+tab.height/2) - end; + end, TabPressedMessageCommand = function(self, params) + if params.name == "Goals" then + SCREENMAN:AddNewScreenToTop("ScreenGoalManager") + end end } diff --git a/BGAnimations/ScreenPlaylistInfo overlay/default.lua b/BGAnimations/ScreenPlaylistInfo overlay/default.lua index 6f35a810..bb564d2c 100644 --- a/BGAnimations/ScreenPlaylistInfo overlay/default.lua +++ b/BGAnimations/ScreenPlaylistInfo overlay/default.lua @@ -147,11 +147,11 @@ local function playlistInfo() local t = Def.ActorFrame{ InitCommand = function(self) self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) - end; + end, ShowPlaylistDetailMessageCommand = function(self, params) playlist = params.playlist self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) - end; + end } t[#t+1] = Def.Quad{ @@ -177,14 +177,14 @@ local function playlistInfo() self:xy(frameWidth/2, 80+50+10) self:zoom(0.4) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) - end; + end, SetCommand = function(self) if playlist then self:settext(playlist:GetName()) else self:settext("No Playlist Selected") end - end; + end } @@ -195,16 +195,16 @@ local function playlistInfo() self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Playlist Info") - end; + end } -- Delete Button t[#t+1] = quadButton(6) .. { - Name = "Delete Button"; + Name = "Delete Button", InitCommand = function(self) self:xy(frameWidth/2, frameHeight-buttonHeight/2-10) self:zoomto(buttonWidth, buttonHeight) - end; + end, TopPressedCommand = function(self) if not playlist then return @@ -216,14 +216,14 @@ local function playlistInfo() self:diffusealpha(1) self:smooth(0.3) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) if playlist then self:diffuse(color(colorConfig:get_data().main.negative)):diffusealpha(0.8) else self:diffuse(color(colorConfig:get_data().main.disabled)):diffusealpha(0.8) end - end; + end } t[#t+1] = LoadFont("Common Bold")..{ @@ -232,15 +232,15 @@ local function playlistInfo() self:zoom(0.4) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Delete Playlist") - end; + end } t[#t+1] = quadButton(6) .. { - Name = "Rename Button"; + Name = "Rename Button", InitCommand = function(self) self:xy(frameWidth/2, frameHeight-buttonHeight/2*3-10*2) self:zoomto(buttonWidth, buttonHeight) - end; + end, TopPressedCommand = function(self) if not playlist then return @@ -249,14 +249,14 @@ local function playlistInfo() self:diffusealpha(1) self:smooth(0.3) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) if playlist then self:diffuse(color(colorConfig:get_data().main.warning)):diffusealpha(0.8) else self:diffuse(color(colorConfig:get_data().main.disabled)):diffusealpha(0.8) end - end; + end } t[#t+1] = LoadFont("Common Bold")..{ @@ -265,15 +265,15 @@ local function playlistInfo() self:zoom(0.4) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Rename Playlist") - end; + end } t[#t+1] = quadButton(6) .. { - Name = "Add Button"; + Name = "Add Button", InitCommand = function(self) self:xy(frameWidth/2, frameHeight-buttonHeight/2*5-10*3) self:zoomto(buttonWidth, buttonHeight) - end; + end, TopPressedCommand = function(self) if not playlist then return @@ -286,14 +286,14 @@ local function playlistInfo() self:diffusealpha(1) self:smooth(0.3) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) if playlist then self:diffuse(color(colorConfig:get_data().main.enabled)):diffusealpha(0.8) else self:diffuse(color(colorConfig:get_data().main.disabled)):diffusealpha(0.8) end - end; + end } t[#t+1] = LoadFont("Common Bold")..{ @@ -302,15 +302,15 @@ local function playlistInfo() self:zoom(0.4) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Add to Playlist") - end; + end } t[#t+1] = quadButton(6) .. { - Name = "Play Button"; + Name = "Play Button", InitCommand = function(self) self:xy(frameWidth/2, frameHeight-buttonHeight/2*7-10*4) self:zoomto(buttonWidth, buttonHeight) - end; + end, TopPressedCommand = function(self) if not playlist or not playlist:IsPlayable() then return @@ -322,17 +322,17 @@ local function playlistInfo() self:diffusealpha(1) self:smooth(0.3) self:diffusealpha(0.8) - end; + end, UpdateStepsListMessageCommand = function(self) self:playcommand("Set") - end; + end, SetCommand = function(self) if playlist and playlist:IsPlayable() then self:diffuse(color(colorConfig:get_data().main.positive)):diffusealpha(0.8) else self:diffuse(color(colorConfig:get_data().main.disabled)):diffusealpha(0.8) end - end; + end } t[#t+1] = LoadFont("Common Bold")..{ @@ -341,7 +341,7 @@ local function playlistInfo() self:zoom(0.4) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Play Playlist") - end; + end } return t @@ -369,7 +369,7 @@ local function playlistList() self:diffusealpha(0) self:xy(itemX, itemY + (i-1)*(itemHeight+itemYSpacing)-10) self:playcommand("Show") - end; + end, ShowCommand = function(self) hidden = false self:y(itemY + (i-1)*(itemHeight+itemYSpacing)-10) @@ -379,11 +379,11 @@ local function playlistList() self:easeOut(1) self:y(itemY + (i-1)*(itemHeight+itemYSpacing)) self:diffusealpha(1) - end; + end, HideCommand = function(self) hidden = true self:y(SCREEN_HEIGHT*10) - end; + end, UpdateListMessageCommand = function(self) -- Pack List updates (e.g. new page) playlistIndex = (curPage-1)*10+i playlist = playlists[playlistIndex] @@ -397,7 +397,7 @@ local function playlistList() self:diffusealpha(0) self:queuecommand("Hide") end - end; + end, ShowPlaylistDetailMessageCommand = function(self, params) if params.index == i then self:finishtweening() @@ -410,17 +410,17 @@ local function playlistList() self:diffusealpha(0) self:playcommand("Hide") end - end; + end, HidePlaylistDetailMessageCommand = function(self) if playlist then self:playcommand("Show") end - end; + end, UpdateStepsListMessageCommand = function(self) if playlist then self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) end - end; + end } t[#t+1] = quadButton(6) .. { @@ -428,7 +428,7 @@ local function playlistList() self:halign(0) self:diffusealpha(0.2) self:zoomto(itemWidth, itemHeight) - end; + end, TopPressedCommand = function(self, params) if hidden then return @@ -449,11 +449,11 @@ local function playlistList() self:diffusealpha(0.4) self:smooth(0.3) self:diffusealpha(0.2) - end; + end, SetCommand = function(self) self:diffusealpha(0.2) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -461,32 +461,32 @@ local function playlistList() self:xy(-10,0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) - end; + end, SetCommand = function(self) self:settextf("%d", playlistIndex) - end; + end, ShowPlaylistDetailMessageCommand = function(self) self:easeOut(0.5) self:diffusealpha(0) - end; + end, HidePlaylistDetailMessageCommand = function(self) self:easeOut(0.5) self:diffusealpha(1) - end; + end } t[#t+1] = Def.Quad{ - Name = "Status"; + Name = "Status", InitCommand = function(self) self:halign(0) self:diffuse(color(colorConfig:get_data().main.highlight)) self:diffusealpha(0.8) self:xy(0, 0) self:zoomto(3, itemHeight) - end; + end, SetCommand = function(self) self:diffuse(getMainColor("highlight")) - end; + end } t[#t+1] = LoadFont("Common Bold")..{ @@ -494,7 +494,7 @@ local function playlistList() self:xy(20,0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) - end; + end, SetCommand = function(self) local msd = playlist:GetAverageRating() self:settextf("%5.2f",playlist:GetAverageRating()) @@ -507,26 +507,26 @@ local function playlistList() self:xy(40,-6):halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) - end; + end, SetCommand = function(self) self:settextf("%s",playlist:GetName()) end } t[#t+1] = LoadFont("Common Normal")..{ - Name = "Size"; + Name = "Size", InitCommand = function(self) self:xy(40,5):halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) - end; + end, SetCommand = function(self) self:settextf("%s Steps",#playlist:GetStepslist()) end } t[#t+1] = quadButton(7) .. { - Name = "Add"; + Name = "Add", InitCommand = function(self) self:xy(itemWidth-5-20, 0) if song and steps then @@ -535,7 +535,7 @@ local function playlistList() self:diffuse(color(colorConfig:get_data().main.disabled)):diffusealpha(0.8) end self:zoomto(40, 17) - end; + end, TopPressedCommand = function(self) if not (steps and song) or hidden then return @@ -548,7 +548,7 @@ local function playlistList() self:diffusealpha(1) self:smooth(0.3) self:diffusealpha(0.8) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -557,7 +557,7 @@ local function playlistList() self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) self:settextf("Add") - end; + end } return t @@ -583,17 +583,17 @@ local function playlistList() self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("Available Playlists") - end; + end } -- Add playlist button t[#t+1] = quadButton(6) .. { - Name = "Add Button"; + Name = "Add Button", InitCommand = function(self) self:xy(frameWidth-50-10, itemY - 30) self:diffuse(color(colorConfig:get_data().main.enabled)):diffusealpha(0.8) self:zoomto(100, 20) - end; + end, TopPressedCommand = function(self) -- Doesn't work yet outside of ScreenSelectMusic apparently. addPlaylist() @@ -601,7 +601,7 @@ local function playlistList() self:diffusealpha(1) self:smooth(0.3) self:diffusealpha(0.8) - end; + end } -- Add playlist button text @@ -611,7 +611,7 @@ local function playlistList() self:zoom(0.4) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:settext("New Playlist") - end; + end } for i=1, maxItems do @@ -646,7 +646,7 @@ local function playlistStepsList() self:diffusealpha(0) self:xy(itemX, itemY + (i-1)*(itemHeight+itemYSpacing)-10) self:playcommand("Hide") - end; + end, ShowCommand = function(self) hidden = false self:y(itemY + (i-1)*(itemHeight+itemYSpacing)-10) @@ -656,13 +656,13 @@ local function playlistStepsList() self:easeOut(1) self:y(itemY + (i-1)*(itemHeight+itemYSpacing)) self:diffusealpha(1) - end; + end, HideCommand = function(self) song = nil steps = nil hidden = true self:y(SCREEN_HEIGHT*10) - end; + end, ShowPlaylistDetailMessageCommand = function(self, params) local key = params.playlist:GetChartkeys()[stepsIndex] if not key then @@ -673,13 +673,13 @@ local function playlistStepsList() self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) self:playcommand("Show") - end; + end, HidePlaylistDetailMessageCommand = function(self) self:stoptweening() self:easeOut(0.5) self:diffusealpha(0) self:queuecommand("Hide") - end; + end, UpdateStepsListMessageCommand = function(self) if not detail then return @@ -702,7 +702,7 @@ local function playlistStepsList() self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) self:playcommand("Show") - end; + end } t[#t+1] = quadButton(6) .. { @@ -710,16 +710,16 @@ local function playlistStepsList() self:halign(0) self:diffusealpha(0.2) self:zoomto(itemWidth, itemHeight) - end; + end, TopPressedCommand = function(self, params) self:finishtweening() self:diffusealpha(0.4) self:smooth(0.3) self:diffusealpha(0.2) - end; + end, SetCommand = function(self) self:diffusealpha(0.2) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -727,21 +727,21 @@ local function playlistStepsList() self:xy(-10,0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) - end; + end, SetCommand = function(self) self:settextf("%d", stepsIndex) - end; + end } t[#t+1] = getClearTypeLampQuad(3, itemHeight)..{ InitCommand = function(self) self:halign(0) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) local scoreList = getScoreTable(pn, '1.0x', steps) self:playcommand("SetClearType", {clearType = getHighestClearType(pn,steps,scoreList)}) - end; + end } t[#t+1] = LoadFont("Common Bold")..{ @@ -749,7 +749,7 @@ local function playlistStepsList() self:xy(20,0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) - end; + end, SetCommand = function(self) local msd = steps:GetMSD(1, 1) self:settextf("%5.2f", msd) @@ -762,30 +762,30 @@ local function playlistStepsList() self:xy(40,-6):halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.4) - end; + end, SetCommand = function(self) self:settextf("%s",song:GetMainTitle()) end } t[#t+1] = LoadFont("Common Normal")..{ - Name = "Size"; + Name = "Size", InitCommand = function(self) self:xy(40,5):halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) - end; + end, SetCommand = function(self) self:settextf("// %s",song:GetDisplayArtist()) end } t[#t+1] = quadButton(7) .. { - Name = "Remove"; + Name = "Remove", InitCommand = function(self) self:xy(itemWidth-5-20, 0) self:zoomto(40, 17) - end; + end, TopPressedCommand = function(self) if not playlist or hidden then return @@ -798,7 +798,7 @@ local function playlistStepsList() self:diffusealpha(1) self:smooth(0.3) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) if song and steps then self:diffuse(color(colorConfig:get_data().main.negative)):diffusealpha(0.8) @@ -814,15 +814,15 @@ local function playlistStepsList() self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) self:settextf("Remove") - end; + end } t[#t+1] = quadButton(7) .. { - Name = "Play"; + Name = "Play", InitCommand = function(self) self:xy(itemWidth-10-60, 0) self:zoomto(40, 17) - end; + end, TopPressedCommand = function(self) if not playlist or hidden then return @@ -835,7 +835,7 @@ local function playlistStepsList() self:diffusealpha(1) self:smooth(0.3) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) if song and steps then self:diffuse(color(colorConfig:get_data().main.positive)):diffusealpha(0.8) @@ -851,7 +851,7 @@ local function playlistStepsList() self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)) self:zoom(0.3) self:settextf("Play") - end; + end } return t @@ -861,12 +861,12 @@ local function playlistStepsList() ShowPlaylistDetailMessageCommand = function(self, params) playlist = params.playlist maxPlaylistPages = math.ceil(playlist:GetNumCharts()/(itemCount)) - end; + end, UpdateStepsListMessageCommand = function(self) if playlist then maxPlaylistPages = math.ceil(playlist:GetNumCharts()/(itemCount)) end - end; + end } @@ -884,7 +884,7 @@ local t = Def.ActorFrame{ top = SCREENMAN:GetTopScreen() top:AddInputCallback(input) MESSAGEMAN:Broadcast("UpdateList") - end; + end } t[#t+1] = playlistInfo() .. { diff --git a/BGAnimations/ScreenProfileLoad overlay.lua b/BGAnimations/ScreenProfileLoad overlay.lua index f3006e71..f77e8388 100644 --- a/BGAnimations/ScreenProfileLoad overlay.lua +++ b/BGAnimations/ScreenProfileLoad overlay.lua @@ -8,11 +8,11 @@ t[#t+1] = Def.Quad{ self:smooth(1) self:diffuse(getMainColor("frame")) self:diffusealpha(0.8) - end; -}; + end +} t[#t+1] = LoadFont("Common Normal")..{ - Text=ScreenString("Loading Profiles"); + Text=ScreenString("Loading Profiles"), InitCommand = function(self) self:Center() self:zoom(0.5) @@ -21,18 +21,18 @@ t[#t+1] = LoadFont("Common Normal")..{ self:diffusealpha(0.8) self:diffuseshift() self:effectcolor1(color("#FFFFFF")):effectcolor2(getMainColor("positive")) - end; + end, OffCommand=function(self) self:linear(0.15):diffusealpha(0) - end; -}; + end +} t[#t+1] = Def.Actor { BeginCommand=function(self) - if SCREENMAN:GetTopScreen():HaveProfileToLoad() then self:sleep(1); end; - self:queuecommand("Load"); - end; - LoadCommand=function() SCREENMAN:GetTopScreen():Continue(); end; -}; + if SCREENMAN:GetTopScreen():HaveProfileToLoad() then self:sleep(1) end + self:queuecommand("Load") + end, + LoadCommand=function() SCREENMAN:GetTopScreen():Continue() end +} return t \ No newline at end of file diff --git a/BGAnimations/ScreenProfileLoad underlay.lua b/BGAnimations/ScreenProfileLoad underlay.lua index 10578edd..6183baf3 100644 --- a/BGAnimations/ScreenProfileLoad underlay.lua +++ b/BGAnimations/ScreenProfileLoad underlay.lua @@ -1,6 +1,6 @@ local t = Def.ActorFrame{} t[#t+1] = LoadActor("_background") -t[#t+1] = LoadActor("_particles"); +t[#t+1] = LoadActor("_particles") return t \ No newline at end of file diff --git a/BGAnimations/ScreenProfileSave overlay.lua b/BGAnimations/ScreenProfileSave overlay.lua index e77abfda..af95c097 100644 --- a/BGAnimations/ScreenProfileSave overlay.lua +++ b/BGAnimations/ScreenProfileSave overlay.lua @@ -8,11 +8,11 @@ t[#t+1] = Def.Quad{ self:smooth(1) self:diffuse(getMainColor("frame")) self:diffusealpha(0.8) - end; -}; + end +} t[#t+1] = LoadFont("Common Normal")..{ - Text=ScreenString("Saving Profiles"); + Text=ScreenString("Saving Profiles"), InitCommand = function(self) self:Center() self:zoom(0.5) @@ -21,18 +21,18 @@ t[#t+1] = LoadFont("Common Normal")..{ self:diffusealpha(0.8) self:diffuseshift() self:effectcolor1(color("#FFFFFF")):effectcolor2(getMainColor("positive")) - end; + end, OffCommand=function(self) self:linear(0.15):diffusealpha(0) - end; -}; + end +} t[#t+1] = Def.Actor { BeginCommand=function(self) - if SCREENMAN:GetTopScreen():HaveProfileToSave() then self:sleep(1); end; - self:queuecommand("Load"); - end; - LoadCommand=function() SCREENMAN:GetTopScreen():Continue(); end; -}; + if SCREENMAN:GetTopScreen():HaveProfileToSave() then self:sleep(1) end + self:queuecommand("Load") + end, + LoadCommand=function() SCREENMAN:GetTopScreen():Continue() end +} return t \ No newline at end of file diff --git a/BGAnimations/ScreenProfileSave underlay.lua b/BGAnimations/ScreenProfileSave underlay.lua index 10578edd..6183baf3 100644 --- a/BGAnimations/ScreenProfileSave underlay.lua +++ b/BGAnimations/ScreenProfileSave underlay.lua @@ -1,6 +1,6 @@ local t = Def.ActorFrame{} t[#t+1] = LoadActor("_background") -t[#t+1] = LoadActor("_particles"); +t[#t+1] = LoadActor("_particles") return t \ No newline at end of file diff --git a/BGAnimations/ScreenScoreInfo overlay/default.lua b/BGAnimations/ScreenScoreInfo overlay/default.lua index cc460bbd..761846e5 100644 --- a/BGAnimations/ScreenScoreInfo overlay/default.lua +++ b/BGAnimations/ScreenScoreInfo overlay/default.lua @@ -17,7 +17,7 @@ local t = Def.ActorFrame { OnCommand = function(self) top = SCREENMAN:GetTopScreen() top:AddInputCallback(input) - end; + end } t[#t+1] = LoadActor("../_mouse") diff --git a/BGAnimations/ScreenSelectAvatar overlay/default.lua b/BGAnimations/ScreenSelectAvatar overlay/default.lua index 88daaa55..82755e9c 100644 --- a/BGAnimations/ScreenSelectAvatar overlay/default.lua +++ b/BGAnimations/ScreenSelectAvatar overlay/default.lua @@ -7,10 +7,11 @@ local frameHeight = 40 -- Height of the top bar local curPage = 1 -- Current Page index local curIndex = 1 -- Current Cursor Index -local curName = PROFILEMAN:GetAvatarName(pn) -- String with the current avatar's filename +local GUID = profile:GetGUID() +local curName = findAvatar(GUID) -- String with the current avatar's filename local lastClickedIndex = 0 -- Last clicked index for double-click detection -local avatarTable = PROFILEMAN:GetAllAvatarNames() -- Table containing the filename of all installed avatars +local avatarTable = FILEMAN:GetDirListing(assetFolders.avatar) -- Table containing the filename of all installed avatars local avatarWidth = 50 -- Self explanatory local avatarHeight = 50 local maxCols = math.floor(capWideScale(7,11)) -- Maximum columns depending on screen aspect ratio. @@ -88,16 +89,16 @@ local function topRow() InitCommand = function(self) self:zoomto(frameWidth, frameHeight) self:diffuse(color("#000000")):diffusealpha(0.8) - end; + end } t[#t+1] = Def.Sprite { InitCommand = function (self) self:x(-frameWidth/2 + 5) self:halign(0) - self:LoadBackground(PROFILEMAN:GetAvatarPath(pn)); + self:LoadBackground(assetFolders.avatar .. findAvatar(GUID)) self:zoomto(30,30) - end; + end } t[#t+1] = LoadFont("Common BLarge") .. { @@ -106,7 +107,7 @@ local function topRow() self:zoom(0.30) self:halign(0) self:settext(profile:GetDisplayName()) - end; + end } t[#t+1] = LoadFont("Common Normal") .. { @@ -115,13 +116,16 @@ local function topRow() self:zoom(0.35) self:halign(0) self:settextf("%s", avatarTable[getAvatarIndex()]) - end; + end, + UpdateAvatarMessageCommand = function(self, params) + self:settextf("%s", avatarTable[getAvatarIndex()]) + end, CursorMovedMessageCommand = function(self, params) self:settextf("%s", avatarTable[getAvatarIndex()]) - end; + end, PageMovedMessageCommand = function(self, params) self:settextf("%s", avatarTable[getAvatarIndex()]) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -130,10 +134,10 @@ local function topRow() self:zoom(0.45) self:halign(1) self:settextf("Page %d/%d", curPage, maxPage) - end; + end, PageMovedMessageCommand = function(self, params) self:settextf("Page %d/%d",params.page, maxPage) - end; + end } t[#t+1] = LoadFont("Common Normal")..{ @@ -142,16 +146,16 @@ local function topRow() self:zoom(0.35) self:halign(1) self:settext("Loading... 0%") - end; + end, PageMovedMessageCommand = function(self, params) self:settext("Loading... 0%") - end; + end, UpdateAvatarMessageCommand = function(self, params) self:settextf("Loading... %0.0f%%",100*params.index/math.min(maxRows*maxCols, #avatarTable-(maxRows*maxCols*(curPage-1)))) - end; + end, UpdateFinishedMessageCommand = function(self, params) self:settextf("Loaded in %0.2f Seconds", params.time) - end; + end } return t @@ -161,17 +165,17 @@ local function avatarBox(i) local avatarName = avatarTable[i] local t = Def.ActorFrame { - Name = tostring(i); + Name = tostring(i), InitCommand = function(self) self:x((((i-1)%maxCols)+1)*avatarHSpacing) self:y(((math.floor((i-1)/maxCols)+1)*avatarVSpacing)-10+50) self:diffusealpha(0) - end; + end, PageMovedMessageCommand = function(self) self:finishtweening() self:easeOut(0.5) self:diffusealpha(0) - end; + end, UpdateAvatarMessageCommand = function(self, params) if params.index == i then if i+((curPage-1)*maxCols*maxRows) > #avatarTable then @@ -183,7 +187,7 @@ local function avatarBox(i) avatarName = avatarTable[i+((curPage-1)*maxCols*maxRows)] -- Load the avatar image - self:GetChild("Avatar"):LoadBackground(ProfileManager:GetAvatarFolderPath()..avatarName); + self:GetChild("Avatar"):LoadBackground(assetFolders.avatar..avatarName) if i == curIndex then self:GetChild("Avatar"):zoomto(avatarHeight+8,avatarWidth+8) self:GetChild("Border"):zoomto(avatarHeight+12,avatarWidth+12) @@ -200,11 +204,11 @@ local function avatarBox(i) end end - end; + end } t[#t+1] = Def.Quad{ - Name = "Border"; + Name = "Border", InitCommand = function(self) self:zoomto(avatarWidth+4, avatarHeight+4) self:queuecommand("Set") @@ -217,7 +221,7 @@ local function avatarBox(i) self:diffuse(getMainColor("frame")):diffusealpha(0.8) - end; + end, CursorMovedMessageCommand = function(self, params) self:finishtweening() if params.index == i then @@ -229,7 +233,7 @@ local function avatarBox(i) self:zoomto(avatarWidth+4, avatarHeight+4) self:diffuse(getMainColor("frame")):diffusealpha(0.8) end - end; + end, PageMovedMessageCommand = function(self, params) self:finishtweening() if params.index == i then @@ -241,7 +245,7 @@ local function avatarBox(i) self:zoomto(avatarWidth+4, avatarHeight+4) self:diffuse(getMainColor("frame")):diffusealpha(0.8) end - end; + end } @@ -249,27 +253,30 @@ local function avatarBox(i) InitCommand = function(self) self:zoomto(avatarWidth, avatarHeight) self:visible(false) - end; + end, TopPressedCommand = function(self, params) -- Move the cursor to this index upon clicking if params.input == "DeviceButton_left mouse button" then -- Save and exit upon double clicking if lastClickedIndex == i then - PROFILEMAN:SaveAvatar(pn, avatarTable[getAvatarIndex()]) + avatarConfig:get_data().avatar[GUID] = avatarTable[getAvatarIndex()] + avatarConfig:set_dirty() + avatarConfig:save() SCREENMAN:GetTopScreen():Cancel() + MESSAGEMAN:Broadcast("AvatarChanged") end lastClickedIndex = i curIndex = i MESSAGEMAN:Broadcast("CursorMoved",{index = i}) end - end; + end } -- Avatar t[#t+1] = Def.Sprite { - Name = "Avatar"; + Name = "Avatar", CursorMovedMessageCommand = function(self, params) self:finishtweening() if params.index == i then @@ -279,7 +286,7 @@ local function avatarBox(i) self:smooth(0.2) self:zoomto(avatarWidth, avatarHeight) end - end; + end, PageMovedMessageCommand = function(self, params) self:finishtweening() if params.index == i then @@ -289,7 +296,7 @@ local function avatarBox(i) self:smooth(0.2) self:zoomto(avatarWidth, avatarHeight) end - end; + end } @@ -305,8 +312,11 @@ local function input(event) end if event.button == "Start" then - PROFILEMAN:SaveAvatar(pn, avatarTable[getAvatarIndex()]) + avatarConfig:get_data().avatar[GUID] = avatarTable[getAvatarIndex()] + avatarConfig:set_dirty() + avatarConfig:save() SCREENMAN:GetTopScreen():Cancel() + MESSAGEMAN:Broadcast("AvatarChanged") end -- We want repeats for these events anyway @@ -353,13 +363,14 @@ local t = Def.ActorFrame { top:AddInputCallback(input) co = coroutine.create(updateAvatars) self:SetUpdateFunction(update) - end; + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end } t[#t+1] = topRow() .. { InitCommand = function(self) self:xy(SCREEN_CENTER_X, 50) - end; + end } t[#t+1] = Def.Quad{ @@ -367,14 +378,14 @@ t[#t+1] = Def.Quad{ self:zoomto(25, 25) self:xy(25, SCREEN_CENTER_Y+25) self:diffuse(getMainColor("frame")):diffusealpha(0.8) - end; + end } t[#t+1] = quadButton(4)..{ InitCommand = function(self) self:zoomto(25, 25) self:xy(25, SCREEN_CENTER_Y+25) self:diffuse(color("#FFFFFF")):diffusealpha(0) - end; + end, TopPressedCommand = function(self, params) if params.input == "DeviceButton_left mouse button" then movePage(-1) @@ -384,22 +395,22 @@ t[#t+1] = quadButton(4)..{ self:diffusealpha(0.2) self:smooth(0.3) self:diffusealpha(0) - end; + end } t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { - Name = "TriangleLeft"; + Name = "TriangleLeft", InitCommand = function(self) self:zoom(0.15) self:diffusealpha(0.8) self:xy(25, SCREEN_CENTER_Y+25) self:rotationz(-90) - end; + end, TweenCommand = function(self) self:finishtweening() self:diffuse(getMainColor('highlight')):diffusealpha(0.8) self:smooth(0.5) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) - end; + end } t[#t+1] = Def.Quad{ @@ -407,14 +418,14 @@ t[#t+1] = Def.Quad{ self:zoomto(25, 25) self:xy(SCREEN_WIDTH-25, SCREEN_CENTER_Y+25) self:diffuse(getMainColor("frame")):diffusealpha(0.8) - end; + end } t[#t+1] = quadButton(4)..{ InitCommand = function(self) self:zoomto(25, 25) self:xy(SCREEN_WIDTH-25, SCREEN_CENTER_Y+25) self:diffuse(color("#FFFFFF")):diffusealpha(0) - end; + end, TopPressedCommand = function(self, params) if params.input == "DeviceButton_left mouse button" then movePage(1) @@ -424,22 +435,22 @@ t[#t+1] = quadButton(4)..{ self:diffusealpha(0.2) self:smooth(0.3) self:diffusealpha(0) - end; + end } t[#t+1] = LoadActor(THEME:GetPathG("", "_triangle")) .. { - Name = "TriangleRight"; + Name = "TriangleRight", InitCommand = function(self) self:zoom(0.15) self:diffusealpha(0.8) self:xy(SCREEN_WIDTH-25, SCREEN_CENTER_Y+25) self:rotationz(90) - end; + end, TweenCommand = function(self) self:finishtweening() self:diffuse(getMainColor('highlight')):diffusealpha(0.8) self:smooth(0.5) self:diffuse(color(colorConfig:get_data().selectMusic.TabContentText)):diffusealpha(0.8) - end; + end } for i=1, math.min(maxRows*maxCols, #avatarTable) do diff --git a/BGAnimations/ScreenSelectMusic StepsDisplayList.lua b/BGAnimations/ScreenSelectMusic StepsDisplayList.lua index b907e238..beb10fda 100644 --- a/BGAnimations/ScreenSelectMusic StepsDisplayList.lua +++ b/BGAnimations/ScreenSelectMusic StepsDisplayList.lua @@ -1,66 +1,35 @@ return Def.StepsDisplayList { - Name="StepsDisplayList"; + Name="StepsDisplayList", CursorP1 = Def.ActorFrame { InitCommand=function(self) self:x(-128+16):player(PLAYER_1) - end; + end, PlayerJoinedMessageCommand=function(self, params) if params.Player == PLAYER_1 then - self:visible(true); - (cmd(zoom,0;bounceend,0.3;zoom,1))(self); - end; - end; + self:visible(true) + self:zoom(0):bounceend(0.3):zoom(1) + end + end, PlayerUnjoinedMessageCommand=function(self, params) if params.Player == PLAYER_1 then - self:visible(true); - (cmd(bouncebegin,0.3;zoom,0))(self); - end; - end; + self:visible(true) + self:bouncebegin(0.3):zoom(0) + end + end, LoadFont("Common Normal") .. { - Text="P1"; + Text="P1", InitCommand=function(self) self:x(-4):diffuse(PlayerColor(PLAYER_1)):shadowlength(1) - end; + end, OnCommand=function(self) self:zoom(0.75) - end; - }; - }; - CursorP2 = Def.ActorFrame { - InitCommand=function(self) - self:x(128-16):player(PLAYER_2) - end; - PlayerJoinedMessageCommand=function(self, params) - if params.Player == PLAYER_2 then - self:visible(true); - (cmd(zoom,0;bounceend,0.3;zoom,1))(self); - end; - end; - PlayerUnjoinedMessageCommand=function(self, params) - if params.Player == PLAYER_2 then - self:visible(true); - (cmd(bouncebegin,0.3;zoom,0))(self); - end; - end; - LoadFont("Common Normal") .. { - Text="P2"; - InitCommand=function(self) - self:x(8):diffuse(PlayerColor(PLAYER_2)):shadowlength(1) - end; - OnCommand=function(self) - self:zoom(0.75) - end; - }; - }; + end + } + }, CursorP1Frame = Def.Actor{ ChangeCommand=function(self) self:stoptweening():decelerate(0.125) - end; - }; - CursorP2Frame = Def.Actor{ - ChangeCommand=function(self) - self:stoptweening():decelerate(0.125) - end; - }; -}; \ No newline at end of file + end + } +} \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic decorations/default.lua b/BGAnimations/ScreenSelectMusic decorations/default.lua index e319fc20..cb021a09 100644 --- a/BGAnimations/ScreenSelectMusic decorations/default.lua +++ b/BGAnimations/ScreenSelectMusic decorations/default.lua @@ -1,83 +1,58 @@ local t = Def.ActorFrame{} -t[#t+1] = LoadActor("songinfo"); +t[#t+1] = LoadActor("songinfo") t[#t+1] = Def.ActorFrame { InitCommand=function(self) self:rotationz(-90):xy(SCREEN_CENTER_X/2-WideScale(get43size(150),150),270) self:delayedFadeIn(5) - end; + end, OffCommand=function(self) self:stoptweening() self:sleep(0.025) self:smooth(0.2) self:diffusealpha(0) - end; + end, OnCommand=function(self) - wheel = SCREENMAN:GetTopScreen():GetMusicWheel() - end; + end, CurrentSongChangedMessageCommand=function(self) self:playcommand("PositionSet") - end; + end, Def.StepsDisplayList { - Name="StepsDisplayListRow"; - + Name="StepsDisplayListRow", CursorP1 = Def.ActorFrame { InitCommand=function(self) self:player(PLAYER_1):rotationz(90):diffusealpha(0.6) - end; + end, PlayerJoinedMessageCommand=function(self, params) if params.Player == PLAYER_1 then self:visible(true) self:zoom(0):bounceend(1):zoom(1) - end; - end; + end + end, PlayerUnjoinedMessageCommand=function(self, params) if params.Player == PLAYER_1 then self:visible(true) self:zoom(0):bounceend(1):zoom(1) - end; - end; + end + end, Def.Quad{ InitCommand=function(self) self:zoomto(65,65):diffuseshift():effectperiod(1):effectcolor1(Alpha(PlayerColor(PLAYER_1), 0.5)):effectcolor2(PlayerColor(PLAYER_1)) - end; - }; - }; + end + } + }, CursorP2 = Def.ActorFrame { - InitCommand=function(self) - self:player(PLAYER_2):diffusealpha(0.6) - end; - PlayerJoinedMessageCommand=function(self, params) - if params.Player == PLAYER_2 then - self:visible(true); - self:zoom(0):bounceend(1):zoom(1) - end; - end; - PlayerUnjoinedMessageCommand=function(self, params) - if params.Player == PLAYER_2 then - self:visible(true); - self:zoom(0):bounceend(1):zoom(1) - end; - end; - Def.Quad{ - InitCommand=function(self) - self:zoomto(65,65):sleep(0.5):diffuseshift():effectperiod(1):effectcolor2(Alpha(PlayerColor(PLAYER_2), 0.5)):effectcolor1(PlayerColor(PLAYER_2)) - end; - }; - }; + }, CursorP1Frame = Def.Actor{ ChangeCommand=function(self) self:stoptweening():easeOut(0.5) - end; - }; + end + }, CursorP2Frame = Def.Actor{ - ChangeCommand=function(self) - self:stoptweening():easeOut(0.5) - end; - }; - }; -}; + } + } +} return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic decorations/net/default.lua b/BGAnimations/ScreenSelectMusic decorations/net/default.lua new file mode 100644 index 00000000..cb021a09 --- /dev/null +++ b/BGAnimations/ScreenSelectMusic decorations/net/default.lua @@ -0,0 +1,58 @@ +local t = Def.ActorFrame{} +t[#t+1] = LoadActor("songinfo") + +t[#t+1] = Def.ActorFrame { + InitCommand=function(self) + self:rotationz(-90):xy(SCREEN_CENTER_X/2-WideScale(get43size(150),150),270) + self:delayedFadeIn(5) + end, + OffCommand=function(self) + self:stoptweening() + self:sleep(0.025) + self:smooth(0.2) + self:diffusealpha(0) + end, + + OnCommand=function(self) + wheel = SCREENMAN:GetTopScreen():GetMusicWheel() + end, + CurrentSongChangedMessageCommand=function(self) + self:playcommand("PositionSet") + end, + Def.StepsDisplayList { + Name="StepsDisplayListRow", + CursorP1 = Def.ActorFrame { + InitCommand=function(self) + self:player(PLAYER_1):rotationz(90):diffusealpha(0.6) + end, + PlayerJoinedMessageCommand=function(self, params) + if params.Player == PLAYER_1 then + self:visible(true) + self:zoom(0):bounceend(1):zoom(1) + end + end, + PlayerUnjoinedMessageCommand=function(self, params) + if params.Player == PLAYER_1 then + self:visible(true) + self:zoom(0):bounceend(1):zoom(1) + end + end, + Def.Quad{ + InitCommand=function(self) + self:zoomto(65,65):diffuseshift():effectperiod(1):effectcolor1(Alpha(PlayerColor(PLAYER_1), 0.5)):effectcolor2(PlayerColor(PLAYER_1)) + end + } + }, + CursorP2 = Def.ActorFrame { + }, + CursorP1Frame = Def.Actor{ + ChangeCommand=function(self) + self:stoptweening():easeOut(0.5) + end + }, + CursorP2Frame = Def.Actor{ + } + } +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic decorations/net/songinfo.lua b/BGAnimations/ScreenSelectMusic decorations/net/songinfo.lua new file mode 100644 index 00000000..2e2203bf --- /dev/null +++ b/BGAnimations/ScreenSelectMusic decorations/net/songinfo.lua @@ -0,0 +1,316 @@ +local topScreen +local song +local group +local wheel + + +local t = Def.ActorFrame{ + InitCommand = function(self) + self:delayedFadeIn(4) + end, + OffCommand = function(self) + self:stoptweening() + self:smooth(0.2) + self:diffusealpha(0) + end, + OnCommand = function(self) + topScreen = SCREENMAN:GetTopScreen() + song = GAMESTATE:GetCurrentSong() + if topScreen then + wheel = topScreen:GetMusicWheel() + end + self:playcommand("Set") + end, + SetCommand = function(self) + song = GAMESTATE:GetCurrentSong() + group = wheel:GetSelectedSection() + GHETTOGAMESTATE:setLastSelectedFolder(group) + + self:GetChild("Banner"):playcommand("Set") + self:GetChild("CDTitle"):playcommand("Set") + self:GetChild("songTitle"):playcommand("Set") + self:GetChild("songLength"):playcommand("Set") + end, + PlayerJoinedMessageCommand = function(self) self:queuecommand("Set") end, + CurrentSongChangedMessageCommand = function(self) self:queuecommand("Set") end, + DisplayLanguageChangedMessageCommand = function(self) self:queuecommand("Set") end +} + +-- The frame around the banner +t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2,120) + self:zoomto(capWideScale(get43size(384),384)+10,capWideScale(get43size(120),120)+50) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end +} + +-- This makes the banner a button to access song info +t[#t+1] = quadButton(1)..{ + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2,120) + self:zoomto(capWideScale(get43size(384),384),capWideScale(get43size(120),120)) + self:visible(false) + end, + TopPressedCommand = function(self, params) + if params.input == "DeviceButton_left mouse button" then + + if song ~= nil then + SCREENMAN:AddNewScreenToTop("ScreenMusicInfo") + + elseif group ~= nil and GAMESTATE:GetSortOrder() == "SortOrder_Group" then + SCREENMAN:AddNewScreenToTop("ScreenGroupInfo") + end + + end + + + end +} + +-- Song banner +t[#t+1] = Def.Sprite { + Name = "Banner", + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2,120) + end, + SetCommand = function(self) + if topScreen:GetName() == "ScreenSelectMusic" or topScreen:GetName() == "ScreenNetSelectMusic" then + local bnpath = nil + if song then + bnpath = song:GetBannerPath() + elseif group then + bnpath = SONGMAN:GetSongGroupBannerPath(group) + end + if not bnpath or bnpath == "" then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) + self:scaletoclipped(capWideScale(get43size(384),384),capWideScale(get43size(120),120)) + end + end +} + +-- The CD title +t[#t+1] = Def.Sprite { + Name = "CDTitle", + InitCommand = function(self) + self:x(SCREEN_CENTER_X/2+(capWideScale(get43size(384),384)/2)-40) + self:y(120-(capWideScale(get43size(120),120)/2)+30) + self:wag():effectmagnitude(0,0,5) + self:diffusealpha(0.8) + end, + SetCommand = function(self) + self:finishtweening() + if song then + if song:HasCDTitle() then + self:visible(true) + self:Load(song:GetCDTitlePath()) + else + self:visible(false) + end + else + self:visible(false) + end + self:playcommand("AdjustSize") + self:smooth(0.5) + self:diffusealpha(1) + end, + AdjustSizeCommand = function(self) + local height = self:GetHeight() + local width = self:GetWidth() + if height >= 60 and width >= 80 then + if height*(80/60) >= width then + self:zoom(60/height) + else + self:zoom(80/width) + end + elseif height >= 60 then + self:zoom(60/height) + elseif width >= 80 then + self:zoom(80/width) + else + self:zoom(1) + end + end, + CurrentSongChangedMessageCommand = function(self) + self:finishtweening() + self:smooth(0.5) + self:diffusealpha(0) + end +} + +-- Label for how many stages we have played +t[#t+1] = LoadFont("Common Bold") .. { + Name="curStage", + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2-capWideScale(get43size(384),384)/2+5,120-12-capWideScale(get43size(60),60)) + self:halign(0) + self:zoom(0.45) + self:maxwidth(capWideScale(get43size(340),340)/0.45) + self:diffuse(color(colorConfig:get_data().selectMusic.BannerText)) + end, + SetCommand = function(self) + self:settextf("%s Stage",FormatNumberAndSuffix(GAMESTATE:GetCurrentStageIndex()+1)) + end +} + +-- Song title // Artist on top of the banner +t[#t+1] = LoadFont("Common Bold") .. { + Name="songTitle", + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2-capWideScale(get43size(384),384)/2+5,132+capWideScale(get43size(60),60)) + self:halign(0) + self:zoom(0.45) + self:maxwidth(capWideScale(get43size(340),340)/0.45) + self:diffuse(color(colorConfig:get_data().selectMusic.BannerText)) + end, + SetCommand = function(self) + + if song then + self:settext(song:GetDisplayMainTitle().." // "..song:GetDisplayArtist()) + else + if wheel then + self:settext(wheel:GetSelectedSection()) + end + end + end +} + + + +-- Song length +t[#t+1] = LoadFont("Common Normal") .. { + Name="songLength", + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2+capWideScale(get43size(384),384)/2-5,132+capWideScale(get43size(60),60)) + self:halign(1) + self:zoom(0.45) + self:maxwidth(capWideScale(get43size(340),340)/0.45) + end, + SetCommand = function(self) + local length = 0 + if song then + length = song:GetStepsSeconds()/getCurRateValue() + end + self:settextf("%s",SecondsToMSS(length)) + self:diffuse(getSongLengthColor(length)) + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end +} + +-- Gradient over banner when rate is not 1.0 +t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2+capWideScale(get43size(384),384)/2,120+capWideScale(get43size(60),60)) + self:zoomto(capWideScale(get43size(384),384),40) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.6) + self:halign(1) + self:valign(1) + self:fadetop(1) + end, + SetCommand = function(self) + if getCurRateValue() == 1 then + self:stoptweening() + self:smooth(0.2) + self:diffusealpha(0) + else + self:stoptweening() + self:smooth(0.2) + self:diffusealpha(0.6) + end + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end +} + +-- Rate text +t[#t+1] = LoadFont("Common Bold") .. { + Name="songTitle", + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2+capWideScale(get43size(384),384)/2-5,110+capWideScale(get43size(60),60)) + self:halign(1) + self:zoom(0.45) + self:maxwidth(capWideScale(get43size(340),340)/0.45) + self:diffuse(color(colorConfig:get_data().selectMusic.BannerText)) + end, + SetCommand = function(self) + if getCurRateValue() == 1 then + self:settext("") + else + self:settext(getCurRateDisplayString()) + end + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end +} + +local function getReady() + local userCount = topScreen:GetUserQty() + local me = NSMAN:GetLoggedInUsername() + local ready = nil + for i = 1, userCount do + if topScreen:GetUser(i) == me then + ready = topScreen:GetUserReady(i) + end + end + return ready +end + +-- Ready button +t[#t+1] = quadButton(6) .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2-capWideScale(get43size(384),384)/2 - 5, 217.5) + self:zoomto(55,25) + self:diffuse(getMainColor("negative")) + self:diffusealpha(0.9) + self:halign(0) + end, + TopPressedCommand = function(self) + NSMAN:SendChatMsg("/ready", 1, NSMAN:GetCurrentRoomName()) + end, + UsersUpdateMessageCommand = function(self) + local ready = getReady() + if ready then + self:diffuse(getMainColor("positive")) + self:diffusealpha(0.9) + else + self:diffuse(getMainColor("negative")) + self:diffusealpha(0.9) + end + end +} +t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2-capWideScale(get43size(384),384)/2 - 5 + 55/2, 217.5) + self:settext("Ready") + self:zoom(0.4) + end +} + +-- Player Options button +t[#t+1] = quadButton(6) .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2-capWideScale(get43size(384),384)/2 - 5 + 57, 217.5) + self:zoomto(55,25) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + self:halign(0) + end, + TopPressedCommand = function(self) + if song then + SCREENMAN:AddNewScreenToTop("ScreenPlayerOptions") + end + end +} +t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(SCREEN_CENTER_X/2-capWideScale(get43size(384),384)/2 - 5 + 55/2 + 57, 216) + self:settext("Player\nOptions") + self:zoom(0.4) + end + +} + + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic decorations/songinfo.lua b/BGAnimations/ScreenSelectMusic decorations/songinfo.lua index 8a9d167c..1d0198f3 100644 --- a/BGAnimations/ScreenSelectMusic decorations/songinfo.lua +++ b/BGAnimations/ScreenSelectMusic decorations/songinfo.lua @@ -7,12 +7,12 @@ local wheel local t = Def.ActorFrame{ InitCommand = function(self) self:delayedFadeIn(4) - end; + end, OffCommand = function(self) self:stoptweening() self:smooth(0.2) self:diffusealpha(0) - end; + end, OnCommand = function(self) topScreen = SCREENMAN:GetTopScreen() song = GAMESTATE:GetCurrentSong() @@ -20,7 +20,7 @@ local t = Def.ActorFrame{ wheel = topScreen:GetMusicWheel() end self:playcommand("Set") - end; + end, SetCommand = function(self) song = GAMESTATE:GetCurrentSong() group = wheel:GetSelectedSection() @@ -30,12 +30,13 @@ local t = Def.ActorFrame{ self:GetChild("CDTitle"):playcommand("Set") self:GetChild("songTitle"):playcommand("Set") self:GetChild("songLength"):playcommand("Set") - end; - PlayerJoinedMessageCommand = function(self) self:queuecommand("Set") end; - CurrentSongChangedMessageCommand = function(self) self:queuecommand("Set") end; - DisplayLanguageChangedMessageCommand = function(self) self:queuecommand("Set") end; -}; + end, + PlayerJoinedMessageCommand = function(self) self:queuecommand("Set") end, + CurrentSongChangedMessageCommand = function(self) self:queuecommand("Set") end, + DisplayLanguageChangedMessageCommand = function(self) self:queuecommand("Set") end +} +-- The frame around the banner t[#t+1] = Def.Quad{ InitCommand = function(self) self:xy(SCREEN_CENTER_X/2,120) @@ -45,12 +46,13 @@ t[#t+1] = Def.Quad{ end } +-- This makes the banner a button to access song info t[#t+1] = quadButton(1)..{ InitCommand = function(self) self:xy(SCREEN_CENTER_X/2,120) self:zoomto(capWideScale(get43size(384),384),capWideScale(get43size(120),120)) self:visible(false) - end; + end, TopPressedCommand = function(self, params) if params.input == "DeviceButton_left mouse button" then @@ -64,35 +66,41 @@ t[#t+1] = quadButton(1)..{ end - end; + end } -- Song banner -t[#t+1] = Def.Banner{ - Name = "Banner"; +t[#t+1] = Def.Sprite { + Name = "Banner", InitCommand = function(self) self:xy(SCREEN_CENTER_X/2,120) - end; + end, SetCommand = function(self) if topScreen:GetName() == "ScreenSelectMusic" or topScreen:GetName() == "ScreenNetSelectMusic" then + local bnpath = nil if song then - self:LoadFromSong(song) + bnpath = song:GetBannerPath() elseif group then - self:LoadFromSongGroup(group) + bnpath = SONGMAN:GetSongGroupBannerPath(group) + end + if not bnpath or bnpath == "" then + bnpath = THEME:GetPathG("Common", "fallback banner") end + self:LoadBackground(bnpath) self:scaletoclipped(capWideScale(get43size(384),384),capWideScale(get43size(120),120)) end - end; + end } +-- The CD title t[#t+1] = Def.Sprite { - Name = "CDTitle"; + Name = "CDTitle", InitCommand = function(self) self:x(SCREEN_CENTER_X/2+(capWideScale(get43size(384),384)/2)-40) self:y(120-(capWideScale(get43size(120),120)/2)+30) self:wag():effectmagnitude(0,0,5) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) self:finishtweening() if song then @@ -104,11 +112,11 @@ t[#t+1] = Def.Sprite { end else self:visible(false) - end; + end self:playcommand("AdjustSize") self:smooth(0.5) self:diffusealpha(1) - end; + end, AdjustSizeCommand = function(self) local height = self:GetHeight() local width = self:GetWidth() @@ -125,45 +133,39 @@ t[#t+1] = Def.Sprite { else self:zoom(1) end - end; + end, CurrentSongChangedMessageCommand = function(self) self:finishtweening() self:smooth(0.5) self:diffusealpha(0) end -}; +} +-- Label for how many stages we have played t[#t+1] = LoadFont("Common Bold") .. { - Name="curStage"; + Name="curStage", InitCommand = function(self) self:xy(SCREEN_CENTER_X/2-capWideScale(get43size(384),384)/2+5,120-12-capWideScale(get43size(60),60)) self:halign(0) self:zoom(0.45) self:maxwidth(capWideScale(get43size(340),340)/0.45) self:diffuse(color(colorConfig:get_data().selectMusic.BannerText)) - end; + end, SetCommand = function(self) - if GAMESTATE:IsEventMode() then - self:settextf("%s Stage",FormatNumberAndSuffix(GAMESTATE:GetCurrentStageIndex()+1)) - else - if topScreen then - self:settextf("%s Stage",StageToLocalizedString(GAMESTATE:GetCurrentStage())) - self:diffuse(StageToColor(GAMESTATE:GetCurrentStage())) - end - end + self:settextf("%s Stage",FormatNumberAndSuffix(GAMESTATE:GetCurrentStageIndex()+1)) end -}; +} -- Song title // Artist on top of the banner t[#t+1] = LoadFont("Common Bold") .. { - Name="songTitle"; + Name="songTitle", InitCommand = function(self) self:xy(SCREEN_CENTER_X/2-capWideScale(get43size(384),384)/2+5,132+capWideScale(get43size(60),60)) self:halign(0) self:zoom(0.45) self:maxwidth(capWideScale(get43size(340),340)/0.45) self:diffuse(color(colorConfig:get_data().selectMusic.BannerText)) - end; + end, SetCommand = function(self) if song then @@ -180,13 +182,13 @@ t[#t+1] = LoadFont("Common Bold") .. { -- Song length t[#t+1] = LoadFont("Common Normal") .. { - Name="songLength"; + Name="songLength", InitCommand = function(self) self:xy(SCREEN_CENTER_X/2+capWideScale(get43size(384),384)/2-5,132+capWideScale(get43size(60),60)) self:halign(1) self:zoom(0.45) self:maxwidth(capWideScale(get43size(340),340)/0.45) - end; + end, SetCommand = function(self) local length = 0 if song then @@ -194,11 +196,11 @@ t[#t+1] = LoadFont("Common Normal") .. { end self:settextf("%s",SecondsToMSS(length)) self:diffuse(getSongLengthColor(length)) - end; - CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end; -}; - + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end +} +-- Gradient over banner when rate is not 1.0 t[#t+1] = Def.Quad{ InitCommand = function(self) self:xy(SCREEN_CENTER_X/2+capWideScale(get43size(384),384)/2,120+capWideScale(get43size(60),60)) @@ -208,7 +210,7 @@ t[#t+1] = Def.Quad{ self:halign(1) self:valign(1) self:fadetop(1) - end; + end, SetCommand = function(self) if getCurRateValue() == 1 then self:stoptweening() @@ -219,28 +221,28 @@ t[#t+1] = Def.Quad{ self:smooth(0.2) self:diffusealpha(0.6) end - end; - CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end; + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end } -- Rate text t[#t+1] = LoadFont("Common Bold") .. { - Name="songTitle"; + Name="songTitle", InitCommand = function(self) self:xy(SCREEN_CENTER_X/2+capWideScale(get43size(384),384)/2-5,110+capWideScale(get43size(60),60)) self:halign(1) self:zoom(0.45) self:maxwidth(capWideScale(get43size(340),340)/0.45) self:diffuse(color(colorConfig:get_data().selectMusic.BannerText)) - end; + end, SetCommand = function(self) if getCurRateValue() == 1 then self:settext("") else self:settext(getCurRateDisplayString()) end - end; - CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end; + end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end } diff --git a/BGAnimations/ScreenSelectMusic overlay/bgm.lua b/BGAnimations/ScreenSelectMusic overlay/bgm.lua index 7e26ee27..64448b43 100644 --- a/BGAnimations/ScreenSelectMusic overlay/bgm.lua +++ b/BGAnimations/ScreenSelectMusic overlay/bgm.lua @@ -1,13 +1,14 @@ local curSong = nil local start = math.max(0,GHETTOGAMESTATE:getLastPlayedSecond()) -local delay = 1 +local delay = 0.02 local startFromPreview = true local loop = themeConfig:get_data().global.SongPreview == 2 local curPath = "" local sampleStart = 0 local musicLength = 0 +local loops = 0 -local test = true +local sampleEvent = false GHETTOGAMESTATE:setLastPlayedSecond(0) @@ -26,37 +27,57 @@ GHETTOGAMESTATE:setLastPlayedSecond(0) local deltaSum = 0 local function playMusic(self, delta) deltaSum = deltaSum + delta - if deltaSum > delay then - deltaSum = 0 - if curSong and curPath then - if startFromPreview then -- When starting from preview point - SOUND:PlayMusicPart(curPath,sampleStart,musicLength-sampleStart,2,2,loop,true,true) - if themeConfig:get_data().global.SongPreview == 3 then - startFromPreview = false - end + if deltaSum > delay and sampleEvent then + local s = GHETTOGAMESTATE:getSSM() + if s:GetName() == "ScreenSelectMusic" then + if s:GetMusicWheel():IsSettled() and loops <= 1 then + deltaSum = 0 + if curSong and curPath then + if startFromPreview then -- When starting from preview point + amountOfWait = musicLength - sampleStart + + SOUND:PlayMusicPart(curPath,sampleStart,amountOfWait,2,2,loop,true,true) + self:SetUpdateFunctionInterval(amountOfWait) - else -- When starting from start of from exit point. - SOUND:PlayMusicPart(curPath,start,musicLength-start,2,2,false,true,false) - start = 0 + if themeConfig:get_data().global.SongPreview == 3 then + startFromPreview = false + end - if themeConfig:get_data().global.SongPreview == 2 then - startFromPreview = true - end + else -- When starting from start of from exit point. + amountOfWait = musicLength - start + + if loops == 1 then + SOUND:PlayMusicPart(curPath,start,amountOfWait,2,2,true,true,false) + else + SOUND:PlayMusicPart(curPath,start,amountOfWait,2,2,false,true,false) + end + self:SetUpdateFunctionInterval(math.max(0.02, amountOfWait)) + start = 0 + if themeConfig:get_data().global.SongPreview == 2 then + startFromPreview = true + end + + end + loops = loops + 1 + end end end - end + else + self:SetUpdateFunctionInterval(0.025) + end end - local t = Def.ActorFrame{ InitCommand = function(self) if themeConfig:get_data().global.SongPreview ~= 1 then self:SetUpdateFunction(playMusic) end - end; + end, CurrentSongChangedMessageCommand = function(self) + sampleEvent = false + loops = 0 SOUND:StopMusic() deltaSum = 0 curSong = GAMESTATE:GetCurrentSong() @@ -69,8 +90,32 @@ local t = Def.ActorFrame{ sampleStart = curSong:GetSampleStart() musicLength = curSong:MusicLengthSeconds() startFromPreview = start == 0 + if themeConfig:get_data().global.SongPreview ~= 1 then + self:SetUpdateFunctionInterval(0.002) + end + end + end, + PlayingSampleMusicMessageCommand = function(self) + sampleEvent = true + if themeConfig:get_data().global.SongPreview ~= 1 then + self:SetUpdateFunctionInterval(0.002) + SOUND:StopMusic() + end + end, + CurrentRateChangedMessageCommand = function(self, params) + if themeConfig:get_data().global.SongPreview ~= 1 then + amountOfWait = amountOfWait / (1 / params.oldRate) / params.rate -- fun math, this works. + self:SetUpdateFunctionInterval(amountOfWait) + end + end, + PreviewNoteFieldDeletedMessageCommand = function(self) + sampleEvent = true + loops = 0 + if themeConfig:get_data().global.SongPreview ~= 1 then + self:SetUpdateFunctionInterval(0.002) + SOUND:StopMusic() end - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic overlay/currentsort.lua b/BGAnimations/ScreenSelectMusic overlay/currentsort.lua index 1eef4986..73b7d18b 100644 --- a/BGAnimations/ScreenSelectMusic overlay/currentsort.lua +++ b/BGAnimations/ScreenSelectMusic overlay/currentsort.lua @@ -38,13 +38,16 @@ local sortTable = { SortOrder_Endless = 'Endless', SortOrder_Length = 'Song Length', SortOrder_Roulette = 'Roulette', - SortOrder_Recent = 'Recently Played' -}; + SortOrder_Recent = 'Recently Played', + SortOrder_Favorites = 'Favorites', +} local function searchInput(event) - local buttonEnum = Enum.Reverse(DeviceButton)[event.DeviceInput.button] - + if event.type == "InputEventType_FirstPress" and (event.DeviceInput.button == "DeviceButton_left mouse button" or event.DeviceInput.button == "DeviceButton_right mouse button") then + MESSAGEMAN:Broadcast("EndSearch") + end if event.type ~= "InputEventType_Release" and active then + local CtrlPressed = INPUTFILTER:IsBeingPressed("left ctrl") or INPUTFILTER:IsBeingPressed("right ctrl") if event.button == "Back" then searchstring = "" wheel:SongSearch(searchstring) @@ -53,6 +56,12 @@ local function searchInput(event) elseif event.button == "Start" then MESSAGEMAN:Broadcast("EndSearch") + elseif event.button == "MenuLeft" then + wheel:Move(-1) + wheel:Move(0) + elseif event.button == "MenuRight" then + wheel:Move(1) + wheel:Move(0) elseif event.DeviceInput.button == "DeviceButton_space" then -- add space to the string searchstring = searchstring.." " @@ -69,14 +78,21 @@ local function searchInput(event) elseif event.DeviceInput.button == "DeviceButton_=" then searchstring = searchstring.."=" + elseif event.DeviceInput.button == "DeviceButton_v" and CtrlPressed then + searchstring = searchstring .. HOOKS:GetClipboard() + else - if buttonEnum > 96 and buttonEnum < 123 then - searchstring = searchstring..event.DeviceInput.button:sub(-1) + if CtrlPressed then + return false + end + if event.char and event.char:match('[%%%+%-%!%@%#%$%^%&%*%(%)%=%_%.%,%:%;%\'%"%>%<%?%/%~%|%w]') and event.char ~= "" then + searchstring = searchstring .. event.char end end if lastsearchstring ~= searchstring then wheel:SongSearch(searchstring) lastsearchstring = searchstring + GHETTOGAMESTATE:setMusicSearch(searchstring) end end end @@ -85,20 +101,24 @@ local t = Def.ActorFrame{ InitCommand = function(self) self:xy(frameX,frameY) SCREENMAN:set_input_redirected(PLAYER_1, false) - end; + end, OnCommand = function(self) - top = SCREENMAN:GetTopScreen() + GHETTOGAMESTATE:setSSM(top) wheel = top:GetMusicWheel() SCREENMAN:GetTopScreen():AddInputCallback(searchInput) self:y(-frameHeight/2) self:smooth(0.5) self:y(frameY) - end; + GHETTOGAMESTATE:checkForReplayToPlay() + end, + GhettoReplayStartMessageCommand = function(self, params) + top:PlayReplay(params.score) + end, OffCommand = function(self) self:smooth(0.5) self:y(-frameHeight/2) - end; + end, StartSearchMessageCommand = function(self) active = true if searchstring == "" then @@ -108,7 +128,7 @@ local t = Def.ActorFrame{ self:GetChild("SortBar"):diffusealpha(1) end SCREENMAN:set_input_redirected(PLAYER_1, true) - end; + end, EndSearchMessageCommand = function(self) SCREENMAN:set_input_redirected(PLAYER_1, false) active = false @@ -117,7 +137,7 @@ local t = Def.ActorFrame{ else self:GetChild("SortBar"):diffusealpha(alphaInactive) end - end; + end, MoveMusicWheelToSongMessageCommand = function(self, param) if #searchstring > 0 then @@ -128,34 +148,33 @@ local t = Def.ActorFrame{ -- The Message sent from ChangeMusic() in the musicwheel goes to the wrong screen (ScreenPlayerProfiles). -- So Send one manually to ScreenSelectMusic. top:PostScreenMessage('SM_SongChanged', 0) - end; -}; - + end +} t[#t+1] = quadButton(4) .. { - Name="CurrentSort"; + Name="CurrentSort", InitCommand = function(self) self:halign(1) self:zoomto(frameWidth,frameHeight) - self:diffuse(getMainColor('highlight')):diffusealpha(0.8); - end; + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + end, TopPressedCommand = function(self) MESSAGEMAN:Broadcast("StartSearch") - end; -}; + end +} t[#t+1] = LoadFont("Common Normal") .. { - Name="SortBar"; + Name="SortBar", InitCommand = function (self) self:x(5-frameWidth) self:halign(0) self:zoom(0.45) self:diffuse(color(colorConfig:get_data().main.headerFrameText)) self:maxwidth((frameWidth-40)/0.45) - end; + end, SortOrderChangedMessageCommand = function(self) self:queuecommand("SetSortOrder") - end; + end, SetSortOrderCommand = function(self) if searchstring == "" then if not active then @@ -181,36 +200,36 @@ t[#t+1] = LoadFont("Common Normal") .. { self:diffusealpha(alphaInactive) end end - end; + end, SortOrderChangedMessageCommand = function(self) self:queuecommand("SetSortOrder") - end; + end, CurrentSongChangedMessageCommand = function(self) self:queuecommand("SetSortOrder") - end; -}; + end +} t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:x(-5):halign(1):zoom(0.3):maxwidth(40/0.45) - end; + end, BeginCommand=function(self) self:queuecommand("Set") - end; + end, SetCommand=function(self) self:diffuse(color(colorConfig:get_data().main.headerFrameText)) local top = SCREENMAN:GetTopScreen() if top:GetName() == "ScreenSelectMusic" or top:GetName() == "ScreenNetSelectMusic" then local wheel = top:GetMusicWheel() self:settextf("%d/%d",wheel:GetCurrentIndex()+1,wheel:GetNumItems()) - end; - end; + end + end, SortOrderChangedMessageCommand = function(self) self:queuecommand("Set") - end; + end, CurrentSongChangedMessageCommand = function(self) self:queuecommand("Set") - end; -}; + end +} return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic overlay/default.lua b/BGAnimations/ScreenSelectMusic overlay/default.lua index 9702156b..f9af992b 100644 --- a/BGAnimations/ScreenSelectMusic overlay/default.lua +++ b/BGAnimations/ScreenSelectMusic overlay/default.lua @@ -4,21 +4,63 @@ local profile = GetPlayerOrMachineProfile(pn) local user = playerConfig:get_data(pn_to_profile_slot(pn)).Username local pass = playerConfig:get_data(pn_to_profile_slot(pn)).Password if isAutoLogin() then - DLMAN:Login(user, pass) + DLMAN:LoginWithToken(user, pass) end +local screenChoices = { + ScreenNetSelectMusic = true, + ScreenSelectMusic = true, +} + +local replayScore +local isEval + local t = Def.ActorFrame{ LoginFailedMessageCommand = function(self) SCREENMAN:SystemMessage("Login Failed!") - end; + end, LoginMessageCommand=function(self) SCREENMAN:SystemMessage("Login Successful!") - end; + GHETTOGAMESTATE:setOnlineStatus("Online") + end, LogOutMessageCommand=function(self) SCREENMAN:SystemMessage("Logged Out!") + GHETTOGAMESTATE:setOnlineStatus("Local") + end, + + TriggerReplayBeginMessageCommand = function(self, params) + replayScore = params.score + isEval = params.isEval + self:sleep(0.1) + self:queuecommand("DelayedReplayBegin") + end, + + DelayedReplayBeginCommand = function(self) + if isEval then + SCREENMAN:GetTopScreen():ShowEvalScreenForScore(replayScore) + else + SCREENMAN:GetTopScreen():PlayReplay(replayScore) + end + end, + + PlayingSampleMusicMessageCommand = function(self) + local leaderboardEnabled = + playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).leaderboardEnabled and DLMAN:IsLoggedIn() + if leaderboardEnabled and GAMESTATE:GetCurrentSteps(PLAYER_1) then + local chartkey = GAMESTATE:GetCurrentSteps(PLAYER_1):GetChartKey() + if screenChoices[SCREENMAN:GetTopScreen():GetName()] then + if SCREENMAN:GetTopScreen():GetMusicWheel():IsSettled() then + DLMAN:RequestChartLeaderBoardFromOnline( + chartkey, + function(leaderboard) + end + ) + end + end + end end } @@ -26,19 +68,19 @@ local t = Def.ActorFrame{ t[#t+1] = Def.Quad{ InitCommand=function(self) self:y(SCREEN_HEIGHT):halign(0):valign(1):zoomto(SCREEN_WIDTH,200):diffuse(getMainColor("background")):fadetop(1) - end; -}; + end +} -t[#t+1] = LoadActor("../_frame"); +t[#t+1] = LoadActor("../_frame") t[#t+1] = LoadActor("profilecard") -t[#t+1] = LoadActor("tabs"); -t[#t+1] = LoadActor("currentsort"); -t[#t+1] = StandardDecorationFromFileOptional("BPMDisplay","BPMDisplay"); -t[#t+1] = StandardDecorationFromFileOptional("BPMLabel","BPMLabel"); -t[#t+1] = LoadActor("../_cursor"); -t[#t+1] = LoadActor("bgm"); +t[#t+1] = LoadActor("tabs") +t[#t+1] = LoadActor("currentsort") +t[#t+1] = StandardDecorationFromFileOptional("BPMDisplay","BPMDisplay") +t[#t+1] = StandardDecorationFromFileOptional("BPMLabel","BPMLabel") +t[#t+1] = LoadActor("../_cursor") +t[#t+1] = LoadActor("bgm") local largeImageText = string.format("%s: %5.2f",profile:GetDisplayName(), profile:GetPlayerRating()) GAMESTATE:UpdateDiscordMenu(largeImageText) diff --git a/BGAnimations/ScreenSelectMusic overlay/net/bgm.lua b/BGAnimations/ScreenSelectMusic overlay/net/bgm.lua new file mode 100644 index 00000000..000f90a5 --- /dev/null +++ b/BGAnimations/ScreenSelectMusic overlay/net/bgm.lua @@ -0,0 +1,127 @@ +local curSong = nil +local start = math.max(0,GHETTOGAMESTATE:getLastPlayedSecond()) +local delay = 0.02 +local startFromPreview = true +local loop = themeConfig:get_data().global.SongPreview == 2 +local curPath = "" +local sampleStart = 0 +local musicLength = 0 +local loops = 0 + +local sampleEvent = false + +GHETTOGAMESTATE:setLastPlayedSecond(0) + +-- SongPreview == 1 (SM STYLE) +-- Disable this stuff, loops from SampleStart to SampleStart+SampleLength + +-- SongPreview == 2 (current osu!) +-- Loops from SampleStart to end of the song. +-- If a player exits midway in a song, play from last point to end of song, then loop from SampleStart. + +-- SongPreview == 3 (old osu!) +-- Play from SampleStart to end of the song. then Loop from the start of the song to the end. +-- If a player exits midway in a song, play from last point to end of song, then loop from start. + + +local deltaSum = 0 +local function playMusic(self, delta) + deltaSum = deltaSum + delta + + if deltaSum > delay and sampleEvent then + local s = GHETTOGAMESTATE:getSSM() + if s:GetName() == "ScreenNetSelectMusic" then + if s:GetMusicWheel():IsSettled() and loops <= 1 then + deltaSum = 0 + if curSong and curPath then + if startFromPreview then -- When starting from preview point + amountOfWait = musicLength - sampleStart + + SOUND:PlayMusicPart(curPath,sampleStart,amountOfWait,2,2,loop,true,true) + self:SetUpdateFunctionInterval(amountOfWait) + + if themeConfig:get_data().global.SongPreview == 3 then + startFromPreview = false + end + + else -- When starting from start of from exit point. + amountOfWait = musicLength - start + + if loops == 1 then + SOUND:PlayMusicPart(curPath,start,amountOfWait,2,2,true,true,false) + else + SOUND:PlayMusicPart(curPath,start,amountOfWait,2,2,false,true,false) + end + self:SetUpdateFunctionInterval(math.max(0.02, amountOfWait)) + start = 0 + + if themeConfig:get_data().global.SongPreview == 2 then + startFromPreview = true + end + + end + loops = loops + 1 + end + end + end + else + self:SetUpdateFunctionInterval(0.025) + end +end + +local t = Def.ActorFrame{ + InitCommand = function(self) + if themeConfig:get_data().global.SongPreview ~= 1 then + self:SetUpdateFunction(playMusic) + end + end, + CurrentSongChangedMessageCommand = function(self) + sampleEvent = false + loops = 0 + SOUND:StopMusic() + deltaSum = 0 + curSong = GAMESTATE:GetCurrentSong() + if curSong ~= nil then + curPath = curSong:GetMusicPath() + if not curPath then + SCREENMAN:SystemMessage("Invalid music file path.") + return + end + sampleStart = curSong:GetSampleStart() + musicLength = curSong:MusicLengthSeconds() + startFromPreview = start == 0 + if themeConfig:get_data().global.SongPreview ~= 1 then + self:SetUpdateFunctionInterval(0.002) + end + end + end, + PlayingSampleMusicMessageCommand = function(self) + sampleEvent = true + if themeConfig:get_data().global.SongPreview ~= 1 then + self:SetUpdateFunctionInterval(0.002) + SOUND:StopMusic() + end + end, + --[[ + --- --- + --- NOTE FOR THE FUTURE: Need to add oldRate to the messages ingame or something. + ------- + --]] + CurrentRateChangedMessageCommand = function(self, params) + if themeConfig:get_data().global.SongPreview ~= 1 and params.oldRate ~= nil then + amountOfWait = amountOfWait / (1 / params.oldRate) / params.rate -- fun math, this works. + self:SetUpdateFunctionInterval(amountOfWait) + end + end, + + PreviewNoteFieldDeletedMessageCommand = function(self) + sampleEvent = true + loops = 0 + if themeConfig:get_data().global.SongPreview ~= 1 then + self:SetUpdateFunctionInterval(0.002) + SOUND:StopMusic() + end + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic overlay/net/currentsort.lua b/BGAnimations/ScreenSelectMusic overlay/net/currentsort.lua new file mode 100644 index 00000000..73b7d18b --- /dev/null +++ b/BGAnimations/ScreenSelectMusic overlay/net/currentsort.lua @@ -0,0 +1,235 @@ +local alphaInactive = 0.7 + +local frameWidth = 280 +local frameHeight = 20 +local frameX = SCREEN_WIDTH-10 +local frameY = 10 + +local searchstring = "" +local lastsearchstring = "" +local englishes = {"a", "b", "c", "d", "e","f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",";"} +local active = false +local top +local wheel +local song + +local sortTable = { + SortOrder_Preferred = 'Preferred', + SortOrder_Group = 'Group', + SortOrder_Title = 'Title', + SortOrder_BPM = 'BPM', + SortOrder_Popularity = 'Popular', + SortOrder_TopGrades = 'Grade', + SortOrder_Artist = 'Artist', + SortOrder_Genre = 'Genre', + SortOrder_BeginnerMeter = 'Beginner Meter', + SortOrder_EasyMeter = 'Easy Meter', + SortOrder_MediumMeter = 'Normal Meter', + SortOrder_HardMeter = 'Hard Meter', + SortOrder_ChallengeMeter = 'Insane Meter', + SortOrder_DoubleEasyMeter = 'Double Easy Meter', + SortOrder_DoubleMediumMeter = 'Double Normal Meter', + SortOrder_DoubleHardMeter = 'Double Hard Meter', + SortOrder_DoubleChallengeMeter = 'Double Insane Meter', + SortOrder_ModeMenu = 'Mode Menu', + SortOrder_AllCourses = 'All Courses', + SortOrder_Nonstop = 'Nonstop', + SortOrder_Oni = 'Oni', + SortOrder_Endless = 'Endless', + SortOrder_Length = 'Song Length', + SortOrder_Roulette = 'Roulette', + SortOrder_Recent = 'Recently Played', + SortOrder_Favorites = 'Favorites', +} + +local function searchInput(event) + if event.type == "InputEventType_FirstPress" and (event.DeviceInput.button == "DeviceButton_left mouse button" or event.DeviceInput.button == "DeviceButton_right mouse button") then + MESSAGEMAN:Broadcast("EndSearch") + end + if event.type ~= "InputEventType_Release" and active then + local CtrlPressed = INPUTFILTER:IsBeingPressed("left ctrl") or INPUTFILTER:IsBeingPressed("right ctrl") + if event.button == "Back" then + searchstring = "" + wheel:SongSearch(searchstring) + MESSAGEMAN:Broadcast("EndSearch") + + elseif event.button == "Start" then + MESSAGEMAN:Broadcast("EndSearch") + + elseif event.button == "MenuLeft" then + wheel:Move(-1) + wheel:Move(0) + elseif event.button == "MenuRight" then + wheel:Move(1) + wheel:Move(0) + elseif event.DeviceInput.button == "DeviceButton_space" then -- add space to the string + searchstring = searchstring.." " + + elseif event.DeviceInput.button == "DeviceButton_backspace" then + if searchstring == "" then + MESSAGEMAN:Broadcast("EndSearch") + else + searchstring = searchstring:sub(1, -2) + end -- remove the last element of the string + + elseif event.DeviceInput.button == "DeviceButton_delete" then + searchstring = "" + + elseif event.DeviceInput.button == "DeviceButton_=" then + searchstring = searchstring.."=" + + elseif event.DeviceInput.button == "DeviceButton_v" and CtrlPressed then + searchstring = searchstring .. HOOKS:GetClipboard() + + else + if CtrlPressed then + return false + end + if event.char and event.char:match('[%%%+%-%!%@%#%$%^%&%*%(%)%=%_%.%,%:%;%\'%"%>%<%?%/%~%|%w]') and event.char ~= "" then + searchstring = searchstring .. event.char + end + end + if lastsearchstring ~= searchstring then + wheel:SongSearch(searchstring) + lastsearchstring = searchstring + GHETTOGAMESTATE:setMusicSearch(searchstring) + end + end +end + +local t = Def.ActorFrame{ + InitCommand = function(self) + self:xy(frameX,frameY) + SCREENMAN:set_input_redirected(PLAYER_1, false) + end, + OnCommand = function(self) + top = SCREENMAN:GetTopScreen() + GHETTOGAMESTATE:setSSM(top) + wheel = top:GetMusicWheel() + SCREENMAN:GetTopScreen():AddInputCallback(searchInput) + self:y(-frameHeight/2) + self:smooth(0.5) + self:y(frameY) + GHETTOGAMESTATE:checkForReplayToPlay() + end, + GhettoReplayStartMessageCommand = function(self, params) + top:PlayReplay(params.score) + end, + OffCommand = function(self) + self:smooth(0.5) + self:y(-frameHeight/2) + end, + StartSearchMessageCommand = function(self) + active = true + if searchstring == "" then + self:GetChild("SortBar"):settext("Type to Search..") + self:GetChild("SortBar"):diffusealpha(alphaInactive) + else + self:GetChild("SortBar"):diffusealpha(1) + end + SCREENMAN:set_input_redirected(PLAYER_1, true) + end, + EndSearchMessageCommand = function(self) + SCREENMAN:set_input_redirected(PLAYER_1, false) + active = false + if searchstring == "" then + self:GetChild("SortBar"):playcommand("SetSortOrder") + else + self:GetChild("SortBar"):diffusealpha(alphaInactive) + end + end, + + MoveMusicWheelToSongMessageCommand = function(self, param) + if #searchstring > 0 then + searchstring = "" + wheel:SongSearch(searchstring) + end + wheel:SelectSong(param.song) + -- The Message sent from ChangeMusic() in the musicwheel goes to the wrong screen (ScreenPlayerProfiles). + -- So Send one manually to ScreenSelectMusic. + top:PostScreenMessage('SM_SongChanged', 0) + end +} + +t[#t+1] = quadButton(4) .. { + Name="CurrentSort", + InitCommand = function(self) + self:halign(1) + self:zoomto(frameWidth,frameHeight) + self:diffuse(getMainColor('highlight')):diffusealpha(0.8) + end, + TopPressedCommand = function(self) + MESSAGEMAN:Broadcast("StartSearch") + end +} + +t[#t+1] = LoadFont("Common Normal") .. { + Name="SortBar", + InitCommand = function (self) + self:x(5-frameWidth) + self:halign(0) + self:zoom(0.45) + self:diffuse(color(colorConfig:get_data().main.headerFrameText)) + self:maxwidth((frameWidth-40)/0.45) + end, + SortOrderChangedMessageCommand = function(self) + self:queuecommand("SetSortOrder") + end, + SetSortOrderCommand = function(self) + if searchstring == "" then + if not active then + local sort = GAMESTATE:GetSortOrder() + local song = GAMESTATE:GetCurrentSong() + if sort == nil then + self:settext("Sort: ") + elseif sort == "SortOrder_Group" and song ~= nil then + self:settext(song:GetGroupName()) + else + self:settext("Sort: "..sortTable[sort]) + end + self:diffusealpha(1) + else + self:settext("Type to Search..") + self:diffusealpha(alphaInactive) + end + else + if active then + self:settext(searchstring) + self:diffusealpha(1) + else + self:diffusealpha(alphaInactive) + end + end + end, + SortOrderChangedMessageCommand = function(self) + self:queuecommand("SetSortOrder") + end, + CurrentSongChangedMessageCommand = function(self) + self:queuecommand("SetSortOrder") + end +} + +t[#t+1] = LoadFont("Common Normal") .. { + InitCommand=function(self) + self:x(-5):halign(1):zoom(0.3):maxwidth(40/0.45) + end, + BeginCommand=function(self) + self:queuecommand("Set") + end, + SetCommand=function(self) + self:diffuse(color(colorConfig:get_data().main.headerFrameText)) + local top = SCREENMAN:GetTopScreen() + if top:GetName() == "ScreenSelectMusic" or top:GetName() == "ScreenNetSelectMusic" then + local wheel = top:GetMusicWheel() + self:settextf("%d/%d",wheel:GetCurrentIndex()+1,wheel:GetNumItems()) + end + end, + SortOrderChangedMessageCommand = function(self) + self:queuecommand("Set") + end, + CurrentSongChangedMessageCommand = function(self) + self:queuecommand("Set") + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic overlay/net/default.lua b/BGAnimations/ScreenSelectMusic overlay/net/default.lua new file mode 100644 index 00000000..3b322c79 --- /dev/null +++ b/BGAnimations/ScreenSelectMusic overlay/net/default.lua @@ -0,0 +1,53 @@ +local pn = GAMESTATE:GetEnabledPlayers()[1] +local profile = GetPlayerOrMachineProfile(pn) + +local user = playerConfig:get_data(pn_to_profile_slot(pn)).Username +local pass = playerConfig:get_data(pn_to_profile_slot(pn)).Password +if isAutoLogin() then + DLMAN:LoginWithToken(user, pass) +end + +local replayScore +local isEval + +local t = Def.ActorFrame{ + OnCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(MPinput) + end, + LoginFailedMessageCommand = function(self) + SCREENMAN:SystemMessage("Login Failed!") + end, + + LoginMessageCommand=function(self) + SCREENMAN:SystemMessage("Login Successful!") + GHETTOGAMESTATE:setOnlineStatus("Online") + end, + + LogOutMessageCommand=function(self) + SCREENMAN:SystemMessage("Logged Out!") + GHETTOGAMESTATE:setOnlineStatus("Local") + end +} + + +t[#t+1] = Def.Quad{ + InitCommand=function(self) + self:y(SCREEN_HEIGHT):halign(0):valign(1):zoomto(SCREEN_WIDTH,200):diffuse(getMainColor("background")):fadetop(1) + end +} + + +t[#t+1] = LoadActor("../../_frame") + +t[#t+1] = LoadActor("profilecard") +t[#t+1] = LoadActor("tabs") +t[#t+1] = LoadActor("currentsort") +t[#t+1] = StandardDecorationFromFileOptional("BPMDisplay","BPMDisplay") +t[#t+1] = StandardDecorationFromFileOptional("BPMLabel","BPMLabel") +t[#t+1] = LoadActor("../../_cursor") +t[#t+1] = LoadActor("bgm") + +local largeImageText = string.format("%s: %5.2f",profile:GetDisplayName(), profile:GetPlayerRating()) +GAMESTATE:UpdateDiscordMenu(largeImageText) + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic overlay/net/profilecard.lua b/BGAnimations/ScreenSelectMusic overlay/net/profilecard.lua new file mode 100644 index 00000000..2a68b2cb --- /dev/null +++ b/BGAnimations/ScreenSelectMusic overlay/net/profilecard.lua @@ -0,0 +1,649 @@ +local t = Def.ActorFrame{ + InitCommand = function(self) + self:delayedFadeIn(6) + end, + OffCommand = function(self) + self:sleep(0.05) + self:smooth(0.2) + self:diffusealpha(0) + end +} + +local frameX = SCREEN_CENTER_X/2 +local frameY = SCREEN_CENTER_Y+86 +local maxMeter = 30 +local frameWidth = capWideScale(get43size(390),390) +local frameHeight = 110 +local frameHeightShort = 61 +local song +local course +local ctags = {} + +local steps = { + PlayerNumber_P1 +} + +local trail = { + PlayerNumber_P1 +} + +local profile = { + PlayerNumber_P1 +} + +local topScore = { + PlayerNumber_P1 +} + +local hsTable = { + PlayerNumber_P1 +} + +local function generalFrame(pn) + local t = Def.ActorFrame{ + SetCommand = function(self) + self:xy(frameX,frameY) + self:visible(GAMESTATE:IsPlayerEnabled(pn)) + end, + + UpdateInfoCommand = function(self) + song = GAMESTATE:GetCurrentSong() + for _,pn in pairs(GAMESTATE:GetEnabledPlayers()) do + profile[pn] = GetPlayerOrMachineProfile(pn) + steps[pn] = GAMESTATE:GetCurrentSteps(pn) + topScore[pn] = getBestScore(pn, 0, getCurRate()) + if song and steps[pn] then + ptags = tags:get_data().playerTags + chartkey = steps[pn]:GetChartKey() + ctags = {} + for k,v in pairs(ptags) do + if ptags[k][chartkey] then + ctags[#ctags + 1] = k + end + end + end + end + self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) + end, + + BeginCommand = function(self) self:playcommand('Set') end, + PlayerJoinedMessageCommand = function(self) self:playcommand("UpdateInfo") end, + PlayerUnjoinedMessageCommand = function(self) self:playcommand("UpdateInfo") end, + CurrentSongChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end, + CurrentStepsP1ChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end + } + + --Upper Bar + t[#t+1] = quadButton(2) .. { + InitCommand = function(self) + self:zoomto(frameWidth,frameHeight) + self:valign(0) + self:diffuse(getMainColor("frame")) + self:diffusealpha(0.8) + end + } + + -- Avatar background frame + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:xy(25+10-(frameWidth/2),5) + self:zoomto(56,56) + self:diffuse(color("#000000")) + self:diffusealpha(0.8) + end, + SetCommand = function(self) + self:stoptweening() + self:smooth(0.5) + self:diffuse(getBorderColor()) + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:xy(25+10-(frameWidth/2),5) + self:zoomto(56,56) + self:diffusealpha(0.8) + end, + BeginCommand = function(self) + self:diffuseramp() + self:effectcolor2(color("1,1,1,0.6")) + self:effectcolor1(color("1,1,1,0")) + self:effecttiming(2,1,0,0) + end + } + + t[#t+1] = quadButton(3) .. { + InitCommand = function(self) + self:xy(25+10-(frameWidth/2),5) + self:zoomto(50,50) + self:visible(false) + end, + TopPressedCommand = function(self, params) + if params.input == "DeviceButton_left mouse button" then + SCREENMAN:AddNewScreenToTop("ScreenPlayerProfile") + end + end + } + + -- Avatar + t[#t+1] = Def.Sprite { + InitCommand = function (self) self:xy(25+10-(frameWidth/2),5):playcommand("ModifyAvatar") end, + PlayerJoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end, + PlayerUnjoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end, + AvatarChangedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end, + ModifyAvatarCommand = function(self) + self:visible(true) + self:LoadBackground(assetFolders.avatar .. findAvatar(PROFILEMAN:GetProfile(PLAYER_1):GetGUID())) + self:zoomto(50,50) + end + } + + -- Player name + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(69-frameWidth/2,9) + self:zoom(0.6) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + local text = "" + if profile[pn] ~= nil then + text = getCurrentUsername(pn) + if text == "" then + text = pn == PLAYER_1 and "Player 1" or "Player 2" + end + end + self:settext(text) + end, + BeginCommand = function(self) self:queuecommand('Set') end, + PlayerJoinedMessageCommand = function(self) self:queuecommand('Set') end, + LoginMessageCommand = function(self) self:queuecommand('Set') end, + LogOutMessageCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(69-frameWidth/2,20) + self:zoom(0.3) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + local rating = 0 + local rank = 0 + local localrating = 0 + + if DLMAN:IsLoggedIn() then + rank = DLMAN:GetSkillsetRank("Overall") + rating = DLMAN:GetSkillsetRating("Overall") + localrating = profile[pn]:GetPlayerRating() + + self:settextf("Skill Rating: %0.2f (%0.2f #%d Online)", localrating, rating, rank) + self:AddAttribute(#"Skill Rating:", {Length = 7, Zoom =0.3 ,Diffuse = getMSDColor(localrating)}) + self:AddAttribute(#"Skill Rating: 00.00 ", {Length = -1, Zoom =0.3 ,Diffuse = getMSDColor(rating)}) + else + if profile[pn] ~= nil then + localrating = profile[pn]:GetPlayerRating() + self:settextf("Skill Rating: %0.2f",localrating) + self:AddAttribute(#"Skill Rating:", {Length = -1, Zoom =0.3 ,Diffuse = getMSDColor(localrating)}) + end + + end + + end, + BeginCommand = function(self) self:queuecommand('Set') end, + PlayerJoinedMessageCommand = function(self) self:queuecommand('Set') end, + LoginMessageCommand = function(self) self:queuecommand('Set') end, + LogOutMessageCommand = function(self) self:queuecommand('Set') end, + OnlineUpdateMessageCommand = function(self) self:queuecommand('Set') end + } + + -- Level and exp + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(69-frameWidth/2,29) + self:zoom(0.3) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + if profile[pn] ~= nil then + local level = getLevel(getProfileExp(pn)) + local currentExp = getProfileExp(pn) - getLvExp(level) + local nextExp = getNextLvExp(level) + self:settextf("Lv.%d (%d/%d)",level, currentExp, nextExp) + end + end, + BeginCommand = function(self) self:queuecommand('Set') end, + PlayerJoinedMessageCommand = function(self) self:queuecommand('Set') end + } + + --Score Date + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(frameWidth/2-5,3) + self:zoom(0.35) + self:halign(1):valign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)):diffusealpha(0.5) + end, + SetCommand = function(self) + if getScoreDate(topScore[pn]) == "" then + self:settext("Date Achieved: 0000-00-00 00:00:00") + else + self:settext("Date Achieved: "..getScoreDate(topScore[pn])) + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + -- Steps info + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(5-frameWidth/2,40) + self:zoom(0.3) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + local diff,stype + local notes,holds,rolls,mines,lifts = 0 + local difftext = "" + + if steps[pn] ~= nil then + notes = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Notes") + holds = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Holds") + rolls = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Rolls") + mines = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Mines") + lifts = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Lifts") + diff = steps[pn]:GetDifficulty() + + + + stype = ToEnumShortString(steps[pn]:GetStepsType()):gsub("%_"," ") + self:settextf("Notes:%s // Holds:%s // Rolls:%s // Mines:%s // Lifts:%s",notes,holds,rolls,mines,lifts) + else + self:settext("") + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name="StepsAndMeter", + InitCommand = function(self) + self:xy(frameWidth/2-5,38) + self:zoom(0.5) + self:halign(1) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + if steps[pn] ~= nil then + + local diff = steps[pn]:GetDifficulty() + local stype = ToEnumShortString(steps[pn]:GetStepsType()):gsub("%_"," ") + local meter = steps[pn]:GetMSD(getCurRateValue(),1) + if meter == 0 then + meter = steps[pn]:GetMeter() + end + meter = math.max(0,meter) + + local difftext + if diff == 'Difficulty_Edit' and IsUsingWideScreen() then + difftext = steps[pn]:GetDescription() + difftext = difftext == '' and getDifficulty(diff) or difftext + else + difftext = getDifficulty(diff) + end + if IsUsingWideScreen() then + self:settextf("%s %s %5.2f", stype, difftext, meter) + else + self:settextf("%s %5.2f", difftext, meter) + end + self:diffuse(getDifficultyColor(GetCustomDifficulty(steps[pn]:GetStepsType(),steps[pn]:GetDifficulty()))) + else + self:settext("") + end + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + Name="MSDAvailability", + InitCommand = function(self) + self:xy(frameWidth/2-5,27) + self:zoom(0.3) + self:halign(1) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + if steps[pn] ~= nil then + + local meter = math.floor(steps[pn]:GetMSD(getCurRateValue(),1)) + if meter == 0 then + self:settext("Default") + self:diffuse(color(colorConfig:get_data().main.disabled)) + else + self:settext("MSD") + self:diffuse(color(colorConfig:get_data().main.enabled)) + end + else + self:settext("") + end + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:xy(5-(frameWidth/2),50) + self:zoomto(frameWidth-10,10) + self:halign(0) + self:diffusealpha(1) + self:diffuse(getMainColor("background")) + end + } + + -- Stepstype and Difficulty meter + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(frameWidth-10-frameWidth/2-2,50) + self:zoom(0.3) + self:settext(maxMeter) + end, + SetCommand = function(self) + if steps[pn] ~= nil then + local diff = getDifficulty(steps[pn]:GetDifficulty()) + local stype = ToEnumShortString(steps[pn]:GetStepsType()):gsub("%_"," ") + self:diffuse(getDifficultyColor(GetCustomDifficulty(steps[pn]:GetStepsType(),steps[pn]:GetDifficulty()))) + end + end + } + + t[#t+1] = Def.Quad{ + InitCommand = function(self) + self:xy(5-(frameWidth/2),50) + self:halign(0) + self:zoomy(10) + self:diffuse(getMainColor("highlight")) + end, + SetCommand = function(self) + self:stoptweening() + self:decelerate(0.5) + local meter = 0 + local enabled = GAMESTATE:IsPlayerEnabled(pn) + if enabled and steps[pn] ~= nil then + meter = steps[pn]:GetMSD(getCurRateValue(),1) + if meter == 0 then + meter = steps[pn]:GetMeter() + end + self:zoomx((math.min(1,meter/maxMeter))*(frameWidth-10)) + self:diffuse(getDifficultyColor(GetCustomDifficulty(steps[pn]:GetStepsType(),steps[pn]:GetDifficulty()))) + else + self:zoomx(0) + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,18) + self:settext("Negative BPMs") + self:zoom(0.4) + self:halign(1) + self:visible(false) + end, + SetCommand = function(self) + if song and steps and steps[pn] then + if steps[pn]:GetTimingData():HasWarps() then + self:visible(true) + return + end + end + self:visible(false) + end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:y(50):zoom(0.3) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + self:stoptweening() + self:decelerate(0.5) + local meter = 0 + local enabled = GAMESTATE:IsPlayerEnabled(pn) + if enabled and steps[pn] ~= nil then + meter = steps[pn]:GetMSD(getCurRateValue(),1) + if meter == 0 then + meter = steps[pn]:GetMeter() + end + meter = math.max(1,meter) + self:settextf("%0.2f", meter) + self:x((math.min(1,meter/maxMeter))*(frameWidth-15)-frameWidth/2-3) + else + self:settext(0) + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + --Grades + t[#t+1] = LoadFont("Common BLarge")..{ + InitCommand = function(self) + self:xy(60-frameWidth/2,frameHeight-35) + self:zoom(0.6) + self:maxwidth(110/0.6) + end, + SetCommand = function(self) + local grade = 'Grade_None' + if topScore[pn] ~= nil then + grade = topScore[pn]:GetWifeGrade() + end + self:settext(THEME:GetString("Grade",ToEnumShortString(grade))) + self:diffuse(getGradeColor(grade)) + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + --ClearType + t[#t+1] = LoadFont("Common Bold")..{ + InitCommand = function(self) + self:xy(60-frameWidth/2,frameHeight-15) + self:zoom(0.4) + self:maxwidth(110/0.4) + end, + SetCommand = function(self) + self:stoptweening() + + local scoreList + local clearType + if profile[pn] ~= nil and song ~= nil and steps[pn] ~= nil then + scoreList = getScoreTable(pn, getCurRate()) + clearType = getHighestClearType(pn,steps[pn],scoreList,0) + self:settext(getClearTypeText(clearType)) + self:diffuse(getClearTypeColor(clearType)) + else + self:settext("") + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + -- Percentage Score + t[#t+1] = LoadFont("Common BLarge")..{ + InitCommand= function(self) + self:xy(190-frameWidth/2,frameHeight-36) + self:zoom(0.45):halign(1):maxwidth(75/0.45) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + local scorevalue = 0 + if topScore[pn] ~= nil then + scorevalue = getScore(topScore[pn], steps[pn], true) + end + self:settextf("%.2f%%",math.floor((scorevalue)*10000)/100) + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + + --Player DP/Exscore / Max DP/Exscore + t[#t+1] = LoadFont("Common Normal")..{ + Name = "score", + InitCommand= function(self) + self:xy(177-frameWidth/2,frameHeight-18) + self:zoom(0.5):halign(1):maxwidth(26/0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + self:settext(getMaxScore(pn,0)) + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand= function(self) + self:xy(177-frameWidth/2,frameHeight-18) + self:zoom(0.5):halign(1):maxwidth(50/0.5) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + self:x(self:GetParent():GetChild("score"):GetX()-(math.min(self:GetParent():GetChild("score"):GetWidth(),27/0.5)*0.5)) + + local scoreValue = 0 + if topScore[pn] ~= nil then + scoreValue = getScore(topScore[pn], steps[pn], false) + end + self:settextf("%.0f/",scoreValue) + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + --ScoreType superscript(?) + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(178-frameWidth/2,frameHeight-19) + self:zoom(0.3) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + BeginCommand = function(self) + self:settext(getScoreTypeText(1)) + end + } + + --MaxCombo + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(210-frameWidth/2,frameHeight-40) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + local score = getBestMaxCombo(pn,0, getCurRate()) + local maxCombo = 0 + maxCombo = getScoreMaxCombo(score) + self:settextf("Max Combo: %d",maxCombo) + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + + --MissCount + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(210-frameWidth/2,frameHeight-28) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + local score = getBestMissCount(pn, 0, getCurRate()) + if score ~= nil then + self:settext("Miss Count: "..getScoreMissCount(score)) + else + self:settext("Miss Count: -") + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + + -- EO rank placeholder + t[#t+1] = LoadFont("Common Normal")..{ + InitCommand = function(self) + self:xy(210-frameWidth/2,frameHeight-16) + self:zoom(0.4) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + end, + SetCommand = function(self) + self:settextf("Ranking: %d/%d",0,0) + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(260 - frameWidth/5, frameHeight-40) + self:zoom(0.4) + self:halign(1) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + self:maxwidth(200) + end, + SetCommand = function(self) + if song and ctags[1] then + self:settext(ctags[1]) + else + self:settext("") + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(260 - frameWidth/5, frameHeight-28) + self:zoom(0.4) + self:halign(1) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + self:maxwidth(200) + end, + SetCommand = function(self) + if song and ctags[2] then + self:settext(ctags[2]) + else + self:settext("") + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(260 - frameWidth/5, frameHeight-16) + self:zoom(0.4) + self:halign(1) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + self:maxwidth(200) + end, + SetCommand = function(self) + if song and ctags[3] then + self:settext(ctags[3]) + else + self:settext("") + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + return t +end + +t[#t+1] = generalFrame(PLAYER_1) + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic overlay/net/tabs.lua b/BGAnimations/ScreenSelectMusic overlay/net/tabs.lua new file mode 100644 index 00000000..b46ecc64 --- /dev/null +++ b/BGAnimations/ScreenSelectMusic overlay/net/tabs.lua @@ -0,0 +1,157 @@ +local inSongSearch = false +local transitioning = false + +local function input(event) + + if event.type == "InputEventType_FirstPress" then + + if event.button == "EffectUp" and not inSongSearch then + changeMusicRate(0.05) + end + + if event.button == "EffectDown" and not inSongSearch then + changeMusicRate(-0.05) + end + + if event.DeviceInput.button == "DeviceButton_mousewheel up" then + wheel:Move(-1) + wheel:Move(0) + end + + if event.DeviceInput.button == "DeviceButton_mousewheel down" then + wheel:Move(1) + wheel:Move(0) + end + + if event.DeviceInput.button == "DeviceButton_middle mouse button" then + lastY = INPUTFILTER:GetMouseY() + end + + local CtrlPressed = INPUTFILTER:IsBeingPressed("left ctrl") or INPUTFILTER:IsBeingPressed("right ctrl") + local numpad = event.DeviceInput.button == "DeviceButton_KP "..event.char + + -- im fired for writing this + if event.DeviceInput.button == "DeviceButton_g" and CtrlPressed then + GHETTOGAMESTATE:resetGoalTable() + wheel:Move(1) + wheel:Move(-1) + wheel:Move(0) + end + if not numpad and event.char and tonumber(event.char) and not inSongSearch and not transitioning then + if tonumber(event.char) == 1 then + SCREENMAN:AddNewScreenToTop("ScreenPlayerProfile") + elseif tonumber(event.char) == 2 then + if GAMESTATE:GetCurrentSong() then + SCREENMAN:AddNewScreenToTop("ScreenNetMusicInfo") + end + elseif tonumber(event.char) == 3 then + SCREENMAN:AddNewScreenToTop("ScreenGroupInfo") + elseif tonumber(event.char) == 4 then + if CtrlPressed then + MESSAGEMAN:Broadcast("StartSearch") + else + GHETTOGAMESTATE:setMusicWheel(SCREENMAN:GetTopScreen()) + SCREENMAN:AddNewScreenToTop("ScreenFiltering") + end + elseif tonumber(event.char) == 5 then + SCREENMAN:AddNewScreenToTop("ScreenDownload") + end + end + + end + + if event.type == "InputEventType_Repeat" then + if event.DeviceInput.button == "DeviceButton_middle mouse button" then + curY = INPUTFILTER:GetMouseY() + if curY-lastY > 0 then + wheel:Move(math.floor((curY-lastY)/50)) + elseif curY-lastY < 0 then + wheel:Move(math.ceil((curY-lastY)/50)) + end + wheel:Move(0) + end + end + + return false + +end + +local lastY +local curY + +local top +local wheel +local t = Def.ActorFrame{ + OnCommand = function(self) + top = SCREENMAN:GetTopScreen() + wheel = SCREENMAN:GetTopScreen():GetMusicWheel() + top:AddInputCallback(input) + self:diffusealpha(0) + self:smooth(0.5) + self:diffusealpha(1) + end, + TriggerReplayBeginMessageCommand = function(self) + transitioning = true + end, + OffCommand = function(self) + transitioning = true + self:smooth(0.5) + self:diffusealpha(0) + end, + StartPlaylistMessageCommand=function(self, params) + top:StartPlaylistAsCourse(params.playlist:GetName()) + end, + StartSearchMessageCommand = function(self) + inSongSearch = true + end, + EndSearchMessageCommand = function(self) + inSongSearch = false + end +} + +t[#t+1] = LoadActor("../../_mouse") + +-- Profile contains: Profile breakdown (local and online) +-- Song Info contains: MSD, Scores, Chart Preview, Online Leaderboard, (and something to let you tag the song) +-- Group info contains: misc info (tags in this pack?) +-- Filtering contains: filters, tags +-- Downloads contains: Downloads, Bundles +local tab = TAB:new({"Profile", "Song Info", "Group Info", "Filtering", "Downloads"}) +t[#t+1] = tab:makeTabActors() .. { + OnCommand = function(self) + self:y(SCREEN_HEIGHT+tab.height/2 - 17) + self:easeOut(0.5) + self:y(SCREEN_HEIGHT-tab.height/2 - 17) + end, + OffCommand = function(self) + self:y(SCREEN_HEIGHT+tab.height/2 - 17) + end, + TabPressedMessageCommand = function(self, params) + if inSongSearch then + MESSAGEMAN:Broadcast("EndSearch") + SCREENMAN:set_input_redirected(PLAYER_1, false) + end + if params.name == "Profile" then + SCREENMAN:AddNewScreenToTop("ScreenPlayerProfile") + elseif params.name == "Song Info" then + if GAMESTATE:GetCurrentSong() then + SCREENMAN:AddNewScreenToTop("ScreenNetMusicInfo") + end + elseif params.name == "Group Info" then + SCREENMAN:AddNewScreenToTop("ScreenGroupInfo") + elseif params.name == "Downloads" then + SCREENMAN:AddNewScreenToTop("ScreenDownload") + elseif params.name == "Filtering" then + GHETTOGAMESTATE:setMusicWheel(top) + SCREENMAN:AddNewScreenToTop("ScreenFiltering") + + --[[ -- Removed playlists for now. They are broken not just in this theme. + elseif params.name == "Playlist" then + SCREENMAN:AddNewScreenToTop("ScreenPlaylistInfo") + ]] + + end + end +} + +return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic overlay/profilecard.lua b/BGAnimations/ScreenSelectMusic overlay/profilecard.lua index f93d13a6..6751a995 100644 --- a/BGAnimations/ScreenSelectMusic overlay/profilecard.lua +++ b/BGAnimations/ScreenSelectMusic overlay/profilecard.lua @@ -1,13 +1,13 @@ local t = Def.ActorFrame{ InitCommand = function(self) self:delayedFadeIn(6) - end; + end, OffCommand = function(self) self:sleep(0.05) self:smooth(0.2) self:diffusealpha(0) - end; -}; + end +} local frameX = SCREEN_CENTER_X/2 local frameY = SCREEN_CENTER_Y+100 @@ -17,41 +17,34 @@ local frameHeight = 110 local frameHeightShort = 61 local song local course +local ctags = {} local steps = { - PlayerNumber_P1, - PlayerNumber_P2 + PlayerNumber_P1 } local trail = { - PlayerNumber_P1, - PlayerNumber_P2 + PlayerNumber_P1 } local profile = { - PlayerNumber_P1, - PlayerNumber_P2 + PlayerNumber_P1 } local topScore = { - PlayerNumber_P1, - PlayerNumber_P2 + PlayerNumber_P1 } local hsTable = { - PlayerNumber_P1, - PlayerNumber_P2 + PlayerNumber_P1 } local function generalFrame(pn) local t = Def.ActorFrame{ SetCommand = function(self) self:xy(frameX,frameY) - if GAMESTATE:GetNumPlayersEnabled() == 2 and pn == PLAYER_2 then - self:x(SCREEN_WIDTH-frameX) - end self:visible(GAMESTATE:IsPlayerEnabled(pn)) - end; + end, UpdateInfoCommand = function(self) song = GAMESTATE:GetCurrentSong() @@ -59,17 +52,26 @@ local function generalFrame(pn) profile[pn] = GetPlayerOrMachineProfile(pn) steps[pn] = GAMESTATE:GetCurrentSteps(pn) topScore[pn] = getBestScore(pn, 0, getCurRate()) + if song and steps[pn] then + ptags = tags:get_data().playerTags + chartkey = steps[pn]:GetChartKey() + ctags = {} + for k,v in pairs(ptags) do + if ptags[k][chartkey] then + ctags[#ctags + 1] = k + end + end + end end self:RunCommandsOnChildren(function(self) self:playcommand("Set") end) - end; - - BeginCommand = function(self) self:playcommand('Set') end; - PlayerJoinedMessageCommand = function(self) self:playcommand("UpdateInfo") end; - PlayerUnjoinedMessageCommand = function(self) self:playcommand("UpdateInfo") end; - CurrentSongChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end; - CurrentStepsP1ChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end; - CurrentStepsP2ChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end; - CurrentRateChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end; + end, + + BeginCommand = function(self) self:playcommand('Set') end, + PlayerJoinedMessageCommand = function(self) self:playcommand("UpdateInfo") end, + PlayerUnjoinedMessageCommand = function(self) self:playcommand("UpdateInfo") end, + CurrentSongChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end, + CurrentStepsP1ChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("UpdateInfo") end } --Upper Bar @@ -79,7 +81,7 @@ local function generalFrame(pn) self:valign(0) self:diffuse(getMainColor("frame")) self:diffusealpha(0.8) - end; + end } -- Avatar background frame @@ -89,13 +91,13 @@ local function generalFrame(pn) self:zoomto(56,56) self:diffuse(color("#000000")) self:diffusealpha(0.8) - end; + end, SetCommand = function(self) self:stoptweening() self:smooth(0.5) self:diffuse(getBorderColor()) - end; - BeginCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end } t[#t+1] = Def.Quad{ @@ -103,13 +105,13 @@ local function generalFrame(pn) self:xy(25+10-(frameWidth/2),5) self:zoomto(56,56) self:diffusealpha(0.8) - end; + end, BeginCommand = function(self) self:diffuseramp() self:effectcolor2(color("1,1,1,0.6")) self:effectcolor1(color("1,1,1,0")) self:effecttiming(2,1,0,0) - end; + end } t[#t+1] = quadButton(3) .. { @@ -117,25 +119,25 @@ local function generalFrame(pn) self:xy(25+10-(frameWidth/2),5) self:zoomto(50,50) self:visible(false) - end; + end, TopPressedCommand = function(self, params) if params.input == "DeviceButton_left mouse button" then SCREENMAN:AddNewScreenToTop("ScreenPlayerProfile") end - end; + end } -- Avatar t[#t+1] = Def.Sprite { - InitCommand = function (self) self:xy(25+10-(frameWidth/2),5):playcommand("ModifyAvatar") end; - PlayerJoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end; - PlayerUnjoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end; - AvatarChangedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end; + InitCommand = function (self) self:xy(25+10-(frameWidth/2),5):playcommand("ModifyAvatar") end, + PlayerJoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end, + PlayerUnjoinedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end, + AvatarChangedMessageCommand = function(self) self:queuecommand('ModifyAvatar') end, ModifyAvatarCommand = function(self) self:visible(true) - self:LoadBackground(PROFILEMAN:GetAvatarPath(pn)); + self:LoadBackground(assetFolders.avatar .. findAvatar(PROFILEMAN:GetProfile(PLAYER_1):GetGUID())) self:zoomto(50,50) - end; + end } -- Player name @@ -145,7 +147,7 @@ local function generalFrame(pn) self:zoom(0.6) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) local text = "" if profile[pn] ~= nil then @@ -155,11 +157,11 @@ local function generalFrame(pn) end end self:settext(text) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - PlayerJoinedMessageCommand = function(self) self:queuecommand('Set') end; - LoginMessageCommand = function(self) self:queuecommand('Set') end; - LogOutMessageCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end, + PlayerJoinedMessageCommand = function(self) self:queuecommand('Set') end, + LoginMessageCommand = function(self) self:queuecommand('Set') end, + LogOutMessageCommand = function(self) self:queuecommand('Set') end } t[#t+1] = LoadFont("Common Normal")..{ @@ -168,32 +170,35 @@ local function generalFrame(pn) self:zoom(0.3) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) local rating = 0 local rank = 0 + local localrating = 0 if DLMAN:IsLoggedIn() then rank = DLMAN:GetSkillsetRank("Overall") rating = DLMAN:GetSkillsetRating("Overall") + localrating = profile[pn]:GetPlayerRating() - self:settextf("Skill Rating: %0.2f (#%d)", rating, rank) - - else + self:settextf("Skill Rating: %0.2f (%0.2f #%d Online)", localrating, rating, rank) + self:AddAttribute(#"Skill Rating:", {Length = 7, Zoom =0.3 ,Diffuse = getMSDColor(localrating)}) + self:AddAttribute(#"Skill Rating: 00.00 ", {Length = -1, Zoom =0.3 ,Diffuse = getMSDColor(rating)}) + else if profile[pn] ~= nil then - rating = profile[pn]:GetPlayerRating() - self:settextf("Skill Rating: %0.2f",rating) + localrating = profile[pn]:GetPlayerRating() + self:settextf("Skill Rating: %0.2f",localrating) + self:AddAttribute(#"Skill Rating:", {Length = -1, Zoom =0.3 ,Diffuse = getMSDColor(localrating)}) end end - self:AddAttribute(#"Skill Rating:", {Length = -1, Zoom =0.3 ,Diffuse = getMSDColor(rating)}) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - PlayerJoinedMessageCommand = function(self) self:queuecommand('Set') end; - LoginMessageCommand = function(self) self:queuecommand('Set') end; - LogOutMessageCommand = function(self) self:queuecommand('Set') end; - OnlineUpdateMessageCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end, + PlayerJoinedMessageCommand = function(self) self:queuecommand('Set') end, + LoginMessageCommand = function(self) self:queuecommand('Set') end, + LogOutMessageCommand = function(self) self:queuecommand('Set') end, + OnlineUpdateMessageCommand = function(self) self:queuecommand('Set') end } -- Level and exp @@ -203,7 +208,7 @@ local function generalFrame(pn) self:zoom(0.3) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) if profile[pn] ~= nil then local level = getLevel(getProfileExp(pn)) @@ -211,9 +216,9 @@ local function generalFrame(pn) local nextExp = getNextLvExp(level) self:settextf("Lv.%d (%d/%d)",level, currentExp, nextExp) end - end; - BeginCommand = function(self) self:queuecommand('Set') end; - PlayerJoinedMessageCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end, + PlayerJoinedMessageCommand = function(self) self:queuecommand('Set') end } --Score Date @@ -223,16 +228,16 @@ local function generalFrame(pn) self:zoom(0.35) self:halign(1):valign(0) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)):diffusealpha(0.5) - end; + end, SetCommand = function(self) if getScoreDate(topScore[pn]) == "" then self:settext("Date Achieved: 0000-00-00 00:00:00") else self:settext("Date Achieved: "..getScoreDate(topScore[pn])) end - end; - BeginCommand = function(self) self:queuecommand('Set') end; - }; + end, + BeginCommand = function(self) self:queuecommand('Set') end + } -- Steps info t[#t+1] = LoadFont("Common Normal")..{ @@ -241,67 +246,49 @@ local function generalFrame(pn) self:zoom(0.3) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) local diff,stype local notes,holds,rolls,mines,lifts = 0 local difftext = "" - if GAMESTATE:IsCourseMode() then - if course:AllSongsAreFixed() then - if trail[pn] ~= nil then - notes = trail[pn]:GetRadarValues(pn):GetValue("RadarCategory_Notes") - holds = trail[pn]:GetRadarValues(pn):GetValue("RadarCategory_Holds") - rolls = trail[pn]:GetRadarValues(pn):GetValue("RadarCategory_Rolls") - mines = trail[pn]:GetRadarValues(pn):GetValue("RadarCategory_Mines") - lifts = trail[pn]:GetRadarValues(pn):GetValue("RadarCategory_Lifts") - diff = trail[pn]:GetDifficulty() - end + if steps[pn] ~= nil then + notes = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Notes") + holds = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Holds") + rolls = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Rolls") + mines = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Mines") + lifts = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Lifts") + diff = steps[pn]:GetDifficulty() - stype = ToEnumShortString(trail[pn]:GetStepsType()):gsub("%_"," ") - self:settextf("%s %s // Notes:%s // Holds:%s // Rolls:%s // Mines:%s // Lifts:%s",stype,diff,notes,holds,rolls,mines,lifts); - else - self:settextf("Disabled for courses containing random songs.") - end + + + stype = ToEnumShortString(steps[pn]:GetStepsType()):gsub("%_"," ") + self:settextf("Notes:%s // Holds:%s // Rolls:%s // Mines:%s // Lifts:%s",notes,holds,rolls,mines,lifts) else - if steps[pn] ~= nil then - notes = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Notes") - holds = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Holds") - rolls = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Rolls") - mines = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Mines") - lifts = steps[pn]:GetRadarValues(pn):GetValue("RadarCategory_Lifts") - diff = steps[pn]:GetDifficulty() - - - - stype = ToEnumShortString(steps[pn]:GetStepsType()):gsub("%_"," ") - self:settextf("Notes:%s // Holds:%s // Rolls:%s // Mines:%s // Lifts:%s",notes,holds,rolls,mines,lifts); - else - self:settext("Disabled"); - end + self:settext("") end - end; - BeginCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end } t[#t+1] = LoadFont("Common Normal")..{ - Name="StepsAndMeter"; + Name="StepsAndMeter", InitCommand = function(self) self:xy(frameWidth/2-5,38) self:zoom(0.5) self:halign(1) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) if steps[pn] ~= nil then local diff = steps[pn]:GetDifficulty() local stype = ToEnumShortString(steps[pn]:GetStepsType()):gsub("%_"," ") - local meter = math.floor(steps[pn]:GetMSD(getCurRateValue(),1)) + local meter = steps[pn]:GetMSD(getCurRateValue(),1) if meter == 0 then meter = steps[pn]:GetMeter() end - meter = math.max(1,meter) + meter = math.max(0,meter) local difftext if diff == 'Difficulty_Edit' and IsUsingWideScreen() then @@ -311,23 +298,25 @@ local function generalFrame(pn) difftext = getDifficulty(diff) end if IsUsingWideScreen() then - self:settext(stype.." "..difftext.." "..meter) + self:settextf("%s %s %5.2f", stype, difftext, meter) else - self:settext(difftext.." "..meter) + self:settextf("%s %5.2f", difftext, meter) end self:diffuse(getDifficultyColor(GetCustomDifficulty(steps[pn]:GetStepsType(),steps[pn]:GetDifficulty()))) + else + self:settext("") end - end; - }; + end + } t[#t+1] = LoadFont("Common Normal")..{ - Name="MSDAvailability"; + Name="MSDAvailability", InitCommand = function(self) self:xy(frameWidth/2-5,27) self:zoom(0.3) self:halign(1) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) if steps[pn] ~= nil then @@ -339,9 +328,11 @@ local function generalFrame(pn) self:settext("MSD") self:diffuse(color(colorConfig:get_data().main.enabled)) end + else + self:settext("") end - end; - }; + end + } t[#t+1] = Def.Quad{ InitCommand = function(self) @@ -359,15 +350,15 @@ local function generalFrame(pn) self:xy(frameWidth-10-frameWidth/2-2,50) self:zoom(0.3) self:settext(maxMeter) - end; + end, SetCommand = function(self) if steps[pn] ~= nil then local diff = getDifficulty(steps[pn]:GetDifficulty()) local stype = ToEnumShortString(steps[pn]:GetStepsType()):gsub("%_"," ") self:diffuse(getDifficultyColor(GetCustomDifficulty(steps[pn]:GetStepsType(),steps[pn]:GetDifficulty()))) end - end; - }; + end + } t[#t+1] = Def.Quad{ InitCommand = function(self) @@ -375,7 +366,7 @@ local function generalFrame(pn) self:halign(0) self:zoomy(10) self:diffuse(getMainColor("highlight")) - end; + end, SetCommand = function(self) self:stoptweening() self:decelerate(0.5) @@ -391,15 +382,34 @@ local function generalFrame(pn) else self:zoomx(0) end - end; - BeginCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameWidth/2-5,18) + self:settext("Negative BPMs") + self:zoom(0.4) + self:halign(1) + self:visible(false) + end, + SetCommand = function(self) + if song and steps and steps[pn] then + if steps[pn]:GetTimingData():HasWarps() then + self:visible(true) + return + end + end + self:visible(false) + end } t[#t+1] = LoadFont("Common Normal")..{ InitCommand = function(self) self:y(50):zoom(0.3) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) self:stoptweening() self:decelerate(0.5) @@ -411,13 +421,13 @@ local function generalFrame(pn) meter = steps[pn]:GetMeter() end meter = math.max(1,meter) - self:settext(math.floor(meter)) - self:x((math.min(1,meter/maxMeter))*(frameWidth-10)-frameWidth/2-3) + self:settextf("%0.2f", meter) + self:x((math.min(1,meter/maxMeter))*(frameWidth-15)-frameWidth/2-3) else self:settext(0) end - end; - BeginCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end } --Grades @@ -426,7 +436,7 @@ local function generalFrame(pn) self:xy(60-frameWidth/2,frameHeight-35) self:zoom(0.6) self:maxwidth(110/0.6) - end; + end, SetCommand = function(self) local grade = 'Grade_None' if topScore[pn] ~= nil then @@ -434,8 +444,8 @@ local function generalFrame(pn) end self:settext(THEME:GetString("Grade",ToEnumShortString(grade))) self:diffuse(getGradeColor(grade)) - end; - BeginCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end } --ClearType @@ -444,7 +454,7 @@ local function generalFrame(pn) self:xy(60-frameWidth/2,frameHeight-15) self:zoom(0.4) self:maxwidth(110/0.4) - end; + end, SetCommand = function(self) self:stoptweening() @@ -455,9 +465,11 @@ local function generalFrame(pn) clearType = getHighestClearType(pn,steps[pn],scoreList,0) self:settext(getClearTypeText(clearType)) self:diffuse(getClearTypeColor(clearType)) + else + self:settext("") end - end; - BeginCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end } -- Percentage Score @@ -466,30 +478,30 @@ local function generalFrame(pn) self:xy(190-frameWidth/2,frameHeight-36) self:zoom(0.45):halign(1):maxwidth(75/0.45) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) local scorevalue = 0 if topScore[pn] ~= nil then scorevalue = getScore(topScore[pn], steps[pn], true) end self:settextf("%.2f%%",math.floor((scorevalue)*10000)/100) - end; - BeginCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end } --Player DP/Exscore / Max DP/Exscore t[#t+1] = LoadFont("Common Normal")..{ - Name = "score"; + Name = "score", InitCommand= function(self) self:xy(177-frameWidth/2,frameHeight-18) self:zoom(0.5):halign(1):maxwidth(26/0.5) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) self:settext(getMaxScore(pn,0)) - end; - BeginCommand = function(self) self:queuecommand('Set') end; + end, + BeginCommand = function(self) self:queuecommand('Set') end } t[#t+1] = LoadFont("Common Normal")..{ @@ -497,7 +509,7 @@ local function generalFrame(pn) self:xy(177-frameWidth/2,frameHeight-18) self:zoom(0.5):halign(1):maxwidth(50/0.5) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) self:x(self:GetParent():GetChild("score"):GetX()-(math.min(self:GetParent():GetChild("score"):GetWidth(),27/0.5)*0.5)) @@ -506,9 +518,9 @@ local function generalFrame(pn) scoreValue = getScore(topScore[pn], steps[pn], false) end self:settextf("%.0f/",scoreValue) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - }; + end, + BeginCommand = function(self) self:queuecommand('Set') end + } --ScoreType superscript(?) t[#t+1] = LoadFont("Common Normal")..{ @@ -517,10 +529,10 @@ local function generalFrame(pn) self:zoom(0.3) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, BeginCommand = function(self) self:settext(getScoreTypeText(1)) - end; + end } --MaxCombo @@ -530,15 +542,15 @@ local function generalFrame(pn) self:zoom(0.4) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) local score = getBestMaxCombo(pn,0, getCurRate()) local maxCombo = 0 maxCombo = getScoreMaxCombo(score) self:settextf("Max Combo: %d",maxCombo) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - }; + end, + BeginCommand = function(self) self:queuecommand('Set') end + } --MissCount @@ -548,7 +560,7 @@ local function generalFrame(pn) self:zoom(0.4) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) local score = getBestMissCount(pn, 0, getCurRate()) if score ~= nil then @@ -556,9 +568,9 @@ local function generalFrame(pn) else self:settext("Miss Count: -") end - end; - BeginCommand = function(self) self:queuecommand('Set') end; - }; + end, + BeginCommand = function(self) self:queuecommand('Set') end + } -- EO rank placeholder @@ -568,19 +580,70 @@ local function generalFrame(pn) self:zoom(0.4) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) - end; + end, SetCommand = function(self) self:settextf("Ranking: %d/%d",0,0) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - }; + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(260 - frameWidth/5, frameHeight-40) + self:zoom(0.4) + self:halign(1) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + self:maxwidth(200) + end, + SetCommand = function(self) + if song and ctags[1] then + self:settext(ctags[1]) + else + self:settext("") + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(260 - frameWidth/5, frameHeight-28) + self:zoom(0.4) + self:halign(1) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + self:maxwidth(200) + end, + SetCommand = function(self) + if song and ctags[2] then + self:settext(ctags[2]) + else + self:settext("") + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } + + t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(260 - frameWidth/5, frameHeight-16) + self:zoom(0.4) + self:halign(1) + self:diffuse(color(colorConfig:get_data().selectMusic.ProfileCardText)) + self:maxwidth(200) + end, + SetCommand = function(self) + if song and ctags[3] then + self:settext(ctags[3]) + else + self:settext("") + end + end, + BeginCommand = function(self) self:queuecommand('Set') end + } return t end t[#t+1] = generalFrame(PLAYER_1) -t[#t+1] = generalFrame(PLAYER_2) - - return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectMusic overlay/tabs.lua b/BGAnimations/ScreenSelectMusic overlay/tabs.lua index e1786f06..cf4bc86f 100644 --- a/BGAnimations/ScreenSelectMusic overlay/tabs.lua +++ b/BGAnimations/ScreenSelectMusic overlay/tabs.lua @@ -1,12 +1,15 @@ +local inSongSearch = false +local transitioning = false + local function input(event) if event.type == "InputEventType_FirstPress" then - if event.button == "EffectUp" then + if event.button == "EffectUp" and not inSongSearch then changeMusicRate(0.05) end - if event.button == "EffectDown" then + if event.button == "EffectDown" and not inSongSearch then changeMusicRate(-0.05) end @@ -24,6 +27,37 @@ local function input(event) lastY = INPUTFILTER:GetMouseY() end + local CtrlPressed = INPUTFILTER:IsBeingPressed("left ctrl") or INPUTFILTER:IsBeingPressed("right ctrl") + local numpad = event.DeviceInput.button == "DeviceButton_KP "..event.char + + -- im fired for writing this + if event.DeviceInput.button == "DeviceButton_g" and CtrlPressed then + GHETTOGAMESTATE:resetGoalTable() + wheel:Move(1) + wheel:Move(-1) + wheel:Move(0) + end + if not numpad and event.char and tonumber(event.char) and not inSongSearch and not transitioning then + if tonumber(event.char) == 1 then + SCREENMAN:AddNewScreenToTop("ScreenPlayerProfile") + elseif tonumber(event.char) == 2 then + if GAMESTATE:GetCurrentSong() then + SCREENMAN:AddNewScreenToTop("ScreenMusicInfo") + end + elseif tonumber(event.char) == 3 then + SCREENMAN:AddNewScreenToTop("ScreenGroupInfo") + elseif tonumber(event.char) == 4 then + if CtrlPressed then + MESSAGEMAN:Broadcast("StartSearch") + else + GHETTOGAMESTATE:setMusicWheel(SCREENMAN:GetTopScreen()) + SCREENMAN:AddNewScreenToTop("ScreenFiltering") + end + elseif tonumber(event.char) == 5 then + SCREENMAN:AddNewScreenToTop("ScreenDownload") + end + end + end if event.type == "InputEventType_Repeat" then @@ -55,46 +89,66 @@ local t = Def.ActorFrame{ self:diffusealpha(0) self:smooth(0.5) self:diffusealpha(1) - end; + end, + TriggerReplayBeginMessageCommand = function(self) + transitioning = true + end, OffCommand = function(self) + transitioning = true self:smooth(0.5) self:diffusealpha(0) - end; + end, StartPlaylistMessageCommand=function(self, params) top:StartPlaylistAsCourse(params.playlist:GetName()) - end; + end, + StartSearchMessageCommand = function(self) + inSongSearch = true + end, + EndSearchMessageCommand = function(self) + inSongSearch = false + end } t[#t+1] = LoadActor("../_mouse") -local tab = TAB:new({"Profile", "Song Info", "Group Info", "Playlist", "Downloads", "Other"}) +-- Profile contains: Profile breakdown (local and online) +-- Song Info contains: MSD, Scores, Chart Preview, Online Leaderboard, (and something to let you tag the song) +-- Group info contains: misc info (tags in this pack?) +-- Filtering contains: filters, tags +-- Downloads contains: Downloads, Bundles +local tab = TAB:new({"Profile", "Song Info", "Group Info", "Filtering", "Downloads"}) t[#t+1] = tab:makeTabActors() .. { OnCommand = function(self) self:y(SCREEN_HEIGHT+tab.height/2) self:easeOut(0.5) self:y(SCREEN_HEIGHT-tab.height/2) - end; + end, OffCommand = function(self) self:y(SCREEN_HEIGHT+tab.height/2) - end; + end, TabPressedMessageCommand = function(self, params) + if inSongSearch then + MESSAGEMAN:Broadcast("EndSearch") + SCREENMAN:set_input_redirected(PLAYER_1, false) + end if params.name == "Profile" then SCREENMAN:AddNewScreenToTop("ScreenPlayerProfile") - elseif params.name == "Song Info" then - if GAMESTATE:GetCurrentSong() then SCREENMAN:AddNewScreenToTop("ScreenMusicInfo") end - elseif params.name == "Group Info" then SCREENMAN:AddNewScreenToTop("ScreenGroupInfo") - elseif params.name == "Downloads" then SCREENMAN:AddNewScreenToTop("ScreenDownload") + elseif params.name == "Filtering" then + GHETTOGAMESTATE:setMusicWheel(top) + SCREENMAN:AddNewScreenToTop("ScreenFiltering") - elseif params.name == "Playlist" then + --[[ -- Removed playlists for now. They are broken not just in this theme. + elseif params.name == "Playlist" then SCREENMAN:AddNewScreenToTop("ScreenPlaylistInfo") + ]] end end diff --git a/BGAnimations/ScreenSelectMusic underlay.lua b/BGAnimations/ScreenSelectMusic underlay.lua index dfcccb80..4250d647 100644 --- a/BGAnimations/ScreenSelectMusic underlay.lua +++ b/BGAnimations/ScreenSelectMusic underlay.lua @@ -1,6 +1,8 @@ local t = Def.ActorFrame{} t[#t+1] = LoadActor("_background") t[#t+1] = LoadActor("_songbg") -t[#t+1] = LoadActor("_particles"); +t[#t+1] = LoadActor("_particles") + +GHETTOGAMESTATE:resetGoalTable() -- refresh the goal table entering SSM return t \ No newline at end of file diff --git a/BGAnimations/ScreenSelectProfile overlay.lua b/BGAnimations/ScreenSelectProfile overlay.lua index 64973aec..b7a7c2af 100644 --- a/BGAnimations/ScreenSelectProfile overlay.lua +++ b/BGAnimations/ScreenSelectProfile overlay.lua @@ -1,9 +1,9 @@ function GetLocalProfiles(pn) - local t = {}; + local t = {} for p = 0,PROFILEMAN:GetNumLocalProfiles()-1 do local profileID = PROFILEMAN:GetLocalProfileIDFromIndex(p) - local profile=PROFILEMAN:GetLocalProfileFromIndex(p); + local profile=PROFILEMAN:GetLocalProfileFromIndex(p) local ProfileCard = Def.ActorFrame { quadButton(1) ..{ @@ -12,187 +12,179 @@ function GetLocalProfiles(pn) self:zoomto(200,40) self:visible(false) self:name(tostring(p)) - end; + end, TopPressedCommand = function(self, params) if params.input == "DeviceButton_left mouse button" then MESSAGEMAN:Broadcast("ProfileLeftClick",{pn = pn,index = tonumber(self:GetName())}) end - end; - }; + end + }, LoadFont("Common Large") .. { - Text=profile:GetDisplayName(); + Text=profile:GetDisplayName(), InitCommand=function(self) self:xy(34/2,-10):zoom(0.4):ztest(true,maxwidth,(200-34-4)/0.4) - end; - }; + end + }, LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(34/2,8):zoom(0.5):vertspacing(-8):ztest(true):maxwidth((200-34-4)/0.5) - end; + end, BeginCommand=function(self) - local numSongsPlayed = profile:GetNumTotalSongsPlayed(); - local s = numSongsPlayed == 1 and "Song" or "Songs"; + local numSongsPlayed = profile:GetNumTotalSongsPlayed() + local s = numSongsPlayed == 1 and "Song" or "Songs" -- todo: localize - self:settext( numSongsPlayed.." "..s.." Played" ); - end; - }; + self:settext( numSongsPlayed.." "..s.." Played" ) + end + }, Def.Sprite { InitCommand=function(self) self:visible(true):halign(0):xy(-98,-2):ztest(true) - end; + end, BeginCommand=function(self) self:queuecommand("ModifyAvatar") - end; + end, ModifyAvatarCommand=function(self) - self:finishtweening(); - self:LoadBackground(PROFILEMAN:GetAvatarPathFromProfileID(ProfileID)); + self:finishtweening() + self:Load(getAssetPathFromProfileID("avatar", profileID)) self:zoomto(30,30) - end; - }; + end + } - }; - t[#t+1]=ProfileCard; - end; + } + t[#t+1]=ProfileCard + end - return t; -end; + return t +end function LoadCard(cColor) local t = Def.ActorFrame { Def.Quad { InitCommand=function(self) self:zoomto(200+10,230+10) - end; + end, OnCommand=function(self) self:diffuse(getMainColor("frame")):diffusealpha(0.8) - end; - }; + end + }, Def.Quad { InitCommand=function(self) self:zoomto(200,230) - end; + end, OnCommand=function(self) self:diffusealpha(0.5):diffuse(cColor) - end; - }; - }; + end + } + } return t end function LoadPlayerStuff(Player) - local t = {}; + local t = {} - local pn = (Player == PLAYER_1) and 1 or 2; + local pn = (Player == PLAYER_1) and 1 or 2 t[#t+1] = Def.ActorFrame { - Name = 'JoinFrame'; - LoadCard(Color('Orange')); + Name = 'JoinFrame', + LoadCard(Color('Orange')), LoadFont("Common Normal") .. { - Text="Press &START; to join."; + Text="Press &START; to join.", InitCommand=function(self) self:shadowlength(1) - end; + end, OnCommand=function(self) self:diffuseshift():effectcolor1(Color('White')):effectcolor2(color("0.5,0.5,0.5")) - end; - }; - }; + end + } + } t[#t+1] = Def.ActorFrame { - Name = 'BigFrame'; - LoadCard(PlayerColor(Player)); - }; + Name = 'BigFrame', + LoadCard(PlayerColor(Player)) + } t[#t+1] = Def.ActorFrame { - Name = 'SmallFrame'; + Name = 'SmallFrame', InitCommand=function(self) self:y(-2) - end; + end, Def.Quad { InitCommand=function(self) self:zoomto(200,40+2) - end; + end, OnCommand=function(self) self:diffusealpha(0.3) - end; - }; - }; + end + } + } t[#t+1] = Def.ActorScroller{ - Name = 'Scroller'; - NumItemsToDraw=6; + Name = 'Scroller', + NumItemsToDraw=6, OnCommand=function(self) self:y(1):SetFastCatchup(true):SetMask(200,58):SetSecondsPerItem(0.15) - end; + end, TransformFunction=function(self, offset, itemIndex, numItems) - local focus = scale(math.abs(offset),0,2,1,0); - self:visible(false); - self:y(math.floor( offset*40 )); - end; - children = GetLocalProfiles(Player); - }; + local focus = scale(math.abs(offset),0,2,1,0) + self:visible(false) + self:y(math.floor( offset*40 )) + end, + children = GetLocalProfiles(Player) + } t[#t+1] = Def.ActorFrame { - Name = "EffectFrame"; - }; + Name = "EffectFrame" + } t[#t+1] = LoadFont("Common Large") .. { - Name = 'SelectedProfileText'; + Name = 'SelectedProfileText', InitCommand=function(self) self:y(160):diffuse(getMainColor("frame")):diffusealpha(0.8):zoom(0.5) - end; - }; + end + } - return t; -end; + return t +end function UpdateInternal3(self, Player) - local pn = (Player == PLAYER_1) and 1 or 2; - local frame = self:GetChild(string.format('P%uFrame', pn)); - local scroller = frame:GetChild('Scroller'); - local seltext = frame:GetChild('SelectedProfileText'); - local joinframe = frame:GetChild('JoinFrame'); - local smallframe = frame:GetChild('SmallFrame'); - local bigframe = frame:GetChild('BigFrame'); + local pn = (Player == PLAYER_1) and 1 or 2 + local frame = self:GetChild(string.format('P%uFrame', pn)) + local scroller = frame:GetChild('Scroller') + local seltext = frame:GetChild('SelectedProfileText') + local joinframe = frame:GetChild('JoinFrame') + local smallframe = frame:GetChild('SmallFrame') + local bigframe = frame:GetChild('BigFrame') if GAMESTATE:IsHumanPlayer(Player) then - frame:visible(true); - if MEMCARDMAN:GetCardState(Player) == 'MemoryCardState_none' then - --using profile if any - joinframe:visible(false); - smallframe:visible(true); - bigframe:visible(true); - seltext:visible(true); - scroller:visible(true); - local ind = SCREENMAN:GetTopScreen():GetProfileIndex(Player); - if ind > 0 then - scroller:SetDestinationItem(ind-1); - seltext:settext(PROFILEMAN:GetLocalProfileFromIndex(ind-1):GetDisplayName()); - else - if SCREENMAN:GetTopScreen():SetProfileIndex(Player, 1) then - scroller:SetDestinationItem(0); - self:queuecommand('UpdateInternal2'); - else - joinframe:visible(true); - smallframe:visible(false); - bigframe:visible(false); - scroller:visible(false); - seltext:settext('No profile'); - end; - end; + frame:visible(true) + --using profile if any + joinframe:visible(false) + smallframe:visible(true) + bigframe:visible(true) + seltext:visible(true) + scroller:visible(true) + local ind = SCREENMAN:GetTopScreen():GetProfileIndex(Player) + if ind > 0 then + scroller:SetDestinationItem(ind-1) + seltext:settext(PROFILEMAN:GetLocalProfileFromIndex(ind-1):GetDisplayName()) else - --using card - smallframe:visible(false); - scroller:visible(false); - seltext:settext('CARD'); - SCREENMAN:GetTopScreen():SetProfileIndex(Player, 0); - end; + if SCREENMAN:GetTopScreen():SetProfileIndex(Player, 1) then + scroller:SetDestinationItem(0) + self:queuecommand('UpdateInternal2') + else + joinframe:visible(true) + smallframe:visible(false) + bigframe:visible(false) + scroller:visible(false) + seltext:settext('No profile') + end + end else - joinframe:visible(true); - scroller:visible(false); - seltext:visible(false); - smallframe:visible(false); - bigframe:visible(false); - end; -end; + joinframe:visible(true) + scroller:visible(false) + seltext:visible(false) + smallframe:visible(false) + bigframe:visible(false) + end +end local t = Def.ActorFrame{ } @@ -203,139 +195,115 @@ t[#t+1] = LoadActor("_mouse") t[#t+1] = Def.ActorFrame{ StorageDevicesChangedMessageCommand=function(self, params) - self:queuecommand('UpdateInternal2'); - end; + self:queuecommand('UpdateInternal2') + end, CodeMessageCommand = function(self, params) if params.Name == 'Start' or params.Name == 'Center' then - MESSAGEMAN:Broadcast("StartButton"); + MESSAGEMAN:Broadcast("StartButton") if not GAMESTATE:IsHumanPlayer(params.PlayerNumber) then - SCREENMAN:GetTopScreen():SetProfileIndex(params.PlayerNumber, -1); + SCREENMAN:GetTopScreen():SetProfileIndex(params.PlayerNumber, -1) else - SCREENMAN:GetTopScreen():Finish(); - end; - end; + SCREENMAN:GetTopScreen():Finish() + end + end if params.Name == 'Up' or params.Name == 'Up2' or params.Name == 'DownLeft' then if GAMESTATE:IsHumanPlayer(params.PlayerNumber) then - local ind = SCREENMAN:GetTopScreen():GetProfileIndex(params.PlayerNumber); + local ind = SCREENMAN:GetTopScreen():GetProfileIndex(params.PlayerNumber) if ind > 1 then if SCREENMAN:GetTopScreen():SetProfileIndex(params.PlayerNumber, ind - 1 ) then - MESSAGEMAN:Broadcast("DirectionButton"); - self:queuecommand('UpdateInternal2'); - end; - end; - end; - end; + MESSAGEMAN:Broadcast("DirectionButton") + self:queuecommand('UpdateInternal2') + end + end + end + end if params.Name == 'Down' or params.Name == 'Down2' or params.Name == 'DownRight' then if GAMESTATE:IsHumanPlayer(params.PlayerNumber) then - local ind = SCREENMAN:GetTopScreen():GetProfileIndex(params.PlayerNumber); + local ind = SCREENMAN:GetTopScreen():GetProfileIndex(params.PlayerNumber) if ind > 0 then if SCREENMAN:GetTopScreen():SetProfileIndex(params.PlayerNumber, ind + 1 ) then - MESSAGEMAN:Broadcast("DirectionButton"); - self:queuecommand('UpdateInternal2'); - end; - end; - end; - end; + MESSAGEMAN:Broadcast("DirectionButton") + self:queuecommand('UpdateInternal2') + end + end + end + end if params.Name == 'Back' then - if GAMESTATE:GetNumPlayersEnabled()==0 then - SCREENMAN:GetTopScreen():Cancel(); - else - MESSAGEMAN:Broadcast("BackButton"); - SCREENMAN:GetTopScreen():SetProfileIndex(params.PlayerNumber, -2); - end; - end; - end; + SCREENMAN:GetTopScreen():Cancel() + end + end, ProfileLeftClickMessageCommand = function(self, params) if GAMESTATE:IsHumanPlayer(params.pn) then - local ind = SCREENMAN:GetTopScreen():GetProfileIndex(params.pn); + local ind = SCREENMAN:GetTopScreen():GetProfileIndex(params.pn) if (params.index+1) - ind == 0 then - MESSAGEMAN:Broadcast("StartButton"); - SCREENMAN:GetTopScreen():Finish(); + MESSAGEMAN:Broadcast("StartButton") + SCREENMAN:GetTopScreen():Finish() else SCREENMAN:GetTopScreen():SetProfileIndex(params.pn, ind + (params.index+1) - ind ) - MESSAGEMAN:Broadcast("DirectionButton"); - self:queuecommand('UpdateInternal2'); - end; - end; - end; + MESSAGEMAN:Broadcast("DirectionButton") + self:queuecommand('UpdateInternal2') + end + end + end, PlayerJoinedMessageCommand=function(self, params) - self:queuecommand('UpdateInternal2'); - end; + self:queuecommand('UpdateInternal2') + end, PlayerUnjoinedMessageCommand=function(self, params) - self:queuecommand('UpdateInternal2'); - end; + self:queuecommand('UpdateInternal2') + end, OnCommand=function(self, params) - self:queuecommand('UpdateInternal2'); - end; + self:queuecommand('UpdateInternal2') + end, UpdateInternal2Command=function(self) - UpdateInternal3(self, PLAYER_1); - UpdateInternal3(self, PLAYER_2); - end; + UpdateInternal3(self, PLAYER_1) + end, children = { Def.ActorFrame { - Name = 'P1Frame'; + Name = 'P1Frame', InitCommand=function(self) self:x(SCREEN_CENTER_X-160):y(SCREEN_CENTER_Y) - end; + end, OnCommand=function(self) self:zoom(0):bounceend(0.35):zoom(1) - end; + end, OffCommand=function(self) self:bouncebegin(0.35):zoom(0) - end; + end, PlayerJoinedMessageCommand=function(self,param) if param.Player == PLAYER_1 then - self:zoom(1.15):bounceend(0.175):zoom(1.0); - end; - end; - children = LoadPlayerStuff(PLAYER_1); - }; - Def.ActorFrame { - Name = 'P2Frame'; - InitCommand=function(self) - self:x(SCREEN_CENTER_X+160):y(SCREEN_CENTER_Y) - end; - OnCommand=function(self) - self:zoom(0):bounceend(0.35):zoom(1) - end; - OffCommand=function(self) - self:bouncebegin(0.35):zoom(0) - end; - PlayerJoinedMessageCommand=function(self,param) - if param.Player == PLAYER_2 then - self:zoom(1.15):bounceend(0.175):zoom(1.0); - end; - end; - children = LoadPlayerStuff(PLAYER_2); - }; + self:zoom(1.15):bounceend(0.175):zoom(1.0) + end + end, + children = LoadPlayerStuff(PLAYER_1) + }, -- sounds LoadActor( THEME:GetPathS("Common","start") )..{ StartButtonMessageCommand=function(self) self:play() - end; - }; + end + }, LoadActor( THEME:GetPathS("Common","cancel") )..{ BackButtonMessageCommand=function(self) self:play() - end; - }; + end + }, LoadActor( THEME:GetPathS("Common","value") )..{ DirectionButtonMessageCommand=function(self) self:play() - end; - }; - }; -}; + end + } + } +} -t[#t+1] = LoadActor("_frame"); -t[#t+1] = LoadActor("_cursor"); +t[#t+1] = LoadActor("_frame") +t[#t+1] = LoadActor("_cursor") -return t; +return t diff --git a/BGAnimations/ScreenSelectStyle decorations.lua b/BGAnimations/ScreenSelectStyle decorations.lua index 9e3d154a..28bcd54f 100644 --- a/BGAnimations/ScreenSelectStyle decorations.lua +++ b/BGAnimations/ScreenSelectStyle decorations.lua @@ -5,15 +5,15 @@ t[#t+1] = Def.Quad{ self:zoomto(150,40) self:Center() self:diffuse(getMainColor("frame")):diffusealpha(0) - end; + end, OnCommand = function(self) - self:smooth(0.5) + self:smooth(0.2) self:diffusealpha(0.8) - end; + end, OffCommand = function(self) - self:smooth(0.5) + self:smooth(0.2) self:diffusealpha(0) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenSystemLayer overlay/default.lua b/BGAnimations/ScreenSystemLayer overlay/default.lua index de7db5b9..9327f51d 100644 --- a/BGAnimations/ScreenSystemLayer overlay/default.lua +++ b/BGAnimations/ScreenSystemLayer overlay/default.lua @@ -2,67 +2,96 @@ local function CreditsText( pn ) local text = LoadFont(Var "LoadingScreen","credits") .. { InitCommand=function(self) self:name("Credits" .. PlayerNumberToString(pn)) - ActorUtil.LoadAllCommandsAndSetXY(self,Var "LoadingScreen"); - end; + ActorUtil.LoadAllCommandsAndSetXY(self,Var "LoadingScreen") + end, UpdateTextCommand=function(self) - local str = ScreenSystemLayerHelpers.GetCreditsMessage(pn); - self:settext(str); - end; + local str = ScreenSystemLayerHelpers.GetCreditsMessage(pn) + self:settext(str) + end, UpdateVisibleCommand=function(self) - local screen = SCREENMAN:GetTopScreen(); - local bShow = true; + local screen = SCREENMAN:GetTopScreen() + local bShow = true if screen then - local sClass = screen:GetName(); - bShow = THEME:GetMetric( sClass, "ShowCreditDisplay" ); + local sClass = screen:GetName() + bShow = THEME:GetMetric( sClass, "ShowCreditDisplay" ) end - self:visible( bShow ); + self:visible( bShow ) end - }; - return text; -end; + } + return text +end local t = Def.ActorFrame {} -t[#t+1] = LoadActor(THEME:GetPathB("ScreenSystemLayer","aux")); - t[#t+1] = Def.ActorFrame { Def.Quad { InitCommand=function(self) self:zoomtowidth(SCREEN_WIDTH):zoomtoheight(30):horizalign(left):vertalign(top):y(SCREEN_TOP):diffuse(color("0,0,0,0")) - end; + end, OnCommand=function(self) self:finishtweening():diffusealpha(0.85) - end; + end, OffCommand=function(self) self:sleep(3):linear(0.5):diffusealpha(0) - end; - }; + end + }, Def.BitmapText{ - Font="Common Normal"; - Name="Text"; + Font="Common Normal", + Name="Text", InitCommand=function(self) self:maxwidth(750):horizalign(left):vertalign(top):y(SCREEN_TOP+10):x(SCREEN_LEFT+10):shadowlength(1):diffusealpha(0) - end; + end, OnCommand=function(self) self:finishtweening():diffusealpha(1):zoom(0.5) - end; + end, OffCommand=function(self) self:sleep(3):linear(0.5):diffusealpha(0) - end; - }; + end + }, SystemMessageMessageCommand = function(self, params) - self:GetChild("Text"):settext( params.Message ); - self:playcommand( "On" ); + self:GetChild("Text"):settext( params.Message ) + self:playcommand( "On" ) if params.NoAnimate then - self:finishtweening(); + self:finishtweening() end - self:playcommand( "Off" ); - end; + self:playcommand( "Off" ) + end, HideSystemMessageMessageCommand = function(self) self:finishtweening() - end; -}; + end +} +-- song reload +local www = 1366 * 0.8 +local hhh = SCREEN_HEIGHT * 0.8 +local rtzoom = 0.6 +t[#t + 1] = + Def.ActorFrame { + DFRStartedMessageCommand = function(self) + self:visible(true) + end, + DFRFinishedMessageCommand = function(self, params) + self:visible(false) + end, + BeginCommand = function(self) + self:visible(false) + self:x(www / 8 + 10):y(SCREEN_BOTTOM - hhh / 8 - 70) + end, + Def.Quad { + InitCommand = function(self) + self:zoomto(www / 4, hhh / 4):diffuse(color("0.1,0.1,0.1,0.8")) + end + }, + Def.BitmapText { + Font = "Common Normal", + InitCommand = function(self) + self:diffusealpha(0.9):settext(""):maxwidth((www / 4 - 40) / rtzoom):zoom(rtzoom) + end, + DFRUpdateMessageCommand = function(self, params) + self:settext(params.txt) + end + } +} -return t; +return t diff --git a/BGAnimations/ScreenTextEntry decorations.lua b/BGAnimations/ScreenTextEntry decorations.lua index 37b2b1d2..388469ff 100644 --- a/BGAnimations/ScreenTextEntry decorations.lua +++ b/BGAnimations/ScreenTextEntry decorations.lua @@ -5,15 +5,15 @@ t[#t+1] = Def.Quad{ self:Center() self:zoomto(SCREEN_WIDTH-250,100) self:diffuse(getMainColor("frame")):diffusealpha(0) - end; + end, OnCommand = function(self) self:smooth(0.5) self:diffusealpha(0.8) - end; + end, OffCommand = function(self) self:smooth(0.5) self:diffusealpha(0) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenTitleMenu underlay.lua b/BGAnimations/ScreenTitleMenu underlay.lua index b002a255..0516e896 100644 --- a/BGAnimations/ScreenTitleMenu underlay.lua +++ b/BGAnimations/ScreenTitleMenu underlay.lua @@ -1,3 +1,7 @@ +if IsSMOnlineLoggedIn() then + CloseConnection() +end + t = Def.ActorFrame{} local frameX = THEME:GetMetric("ScreenTitleMenu","ScrollerX")-10 @@ -5,73 +9,73 @@ local frameY = THEME:GetMetric("ScreenTitleMenu","ScrollerY") t[#t+1] = Def.Quad{ InitCommand=function(self) - self:draworder(-300):xy(frameX,frameY):zoomto(SCREEN_WIDTH,120):halign(0):diffuse(getMainColor('highlight')):diffusealpha(1) + self:draworder(-300):xy(frameX,frameY):zoomto(SCREEN_WIDTH,136):halign(0):diffuse(getMainColor('highlight')):diffusealpha(1) end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) - self:xy(SCREEN_WIDTH-5,frameY-60):zoom(0.5):valign(1):halign(1) - end; + self:xy(SCREEN_WIDTH-5,frameY-70):zoom(0.5):valign(1):halign(1) + end, OnCommand=function(self) - self:settext(string.format("%s v%s %s",getThemeName(),getThemeVersion(),getThemeDate())); - end; + self:settext(string.format("%s v%s %s",getThemeName(),getThemeVersion(),getThemeDate())) + end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(5,5):zoom(0.4):valign(0):halign(0) - end; + end, OnCommand=function(self) - self:settext(string.format("%s %s",ProductFamily(),ProductVersion())); - end; + self:settext(string.format("%s %s",ProductFamily(),ProductVersion())) + end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(5,16):zoom(0.3):valign(0):halign(0) - end; + end, OnCommand=function(self) - self:settext(string.format("%s %s",VersionDate(),VersionTime())); - end; + self:settext(string.format("%s %s",VersionDate(),VersionTime())) + end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(5,25):zoom(0.3):valign(0):halign(0) - end; + end, OnCommand=function(self) - self:settext(string.format("%s Songs in %s Groups",SONGMAN:GetNumSongs(),SONGMAN:GetNumSongGroups())); - end; + self:settext(string.format("%s Songs in %s Groups",SONGMAN:GetNumSongs(),SONGMAN:GetNumSongGroups())) + end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(5,SCREEN_HEIGHT-15):zoom(0.4):valign(1):halign(0) - end; + end, OnCommand=function(self) if IsNetSMOnline() then self:settext("Online") self:diffuse(getMainColor('enabled')) else - self:settext("Offline"); + self:settext("Offline") self:diffuse(getMainColor('disabled')) - end; - end; + end + end } t[#t+1] = LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(5,SCREEN_HEIGHT-5):zoom(0.35):valign(1):halign(0):diffuse(color("#666666")) - end; + end, OnCommand=function(self) if IsNetSMOnline() then self:settext(GetServerName()) self:diffuse(color("#FFFFFF")) else - self:settext("Not Available"); - end; - end; + self:settext("Not Available") + end + end } return t \ No newline at end of file diff --git a/BGAnimations/ScreenWithMenuElements underlay.lua b/BGAnimations/ScreenWithMenuElements underlay.lua index fe657b95..2a9caaea 100644 --- a/BGAnimations/ScreenWithMenuElements underlay.lua +++ b/BGAnimations/ScreenWithMenuElements underlay.lua @@ -1,5 +1,5 @@ local t = Def.ActorFrame{} t[#t+1] = LoadActor("_background") -t[#t+1] = LoadActor("_particles"); +t[#t+1] = LoadActor("_particles") return t \ No newline at end of file diff --git a/BGAnimations/_background.lua b/BGAnimations/_background.lua index b456ddbb..b69ec0b0 100644 --- a/BGAnimations/_background.lua +++ b/BGAnimations/_background.lua @@ -1,5 +1,5 @@ return Def.Quad{ InitCommand=function(self) self:FullScreen():diffuse(getMainColor("background")) - end; + end } \ No newline at end of file diff --git a/BGAnimations/_blank.lua b/BGAnimations/_blank.lua index 871d00f2..082f70d3 100644 --- a/BGAnimations/_blank.lua +++ b/BGAnimations/_blank.lua @@ -1 +1 @@ -return Def.Actor{}; \ No newline at end of file +return Def.Actor{} \ No newline at end of file diff --git a/BGAnimations/_chatbox.lua b/BGAnimations/_chatbox.lua deleted file mode 100644 index 09a34265..00000000 --- a/BGAnimations/_chatbox.lua +++ /dev/null @@ -1,29 +0,0 @@ -local t = Def.ActorFrame{} - -local border = 5 - -local inputX = THEME:GetMetric("ScreenNetSelectBase","ChatInputX") -local inputY = THEME:GetMetric("ScreenNetSelectBase","ChatInputY") -local inputWidth = THEME:GetMetric("ScreenNetSelectBase","ChatTextInputWidth")*0.5 -local inputHeight = 10 - - -local outputX = THEME:GetMetric("ScreenNetSelectBase","ChatOutputX") -local outputY = THEME:GetMetric("ScreenNetSelectBase","ChatOutputY") -local outputWidth = THEME:GetMetric("ScreenNetSelectBase","ChatTextOutputWidth")*0.5 -local outputHeight = THEME:GetMetric("ScreenNetSelectBase","ChatOutputLines")*16 - - -t[#t+1] = Def.Quad{ - InitCommand=function(self) - self:xy(inputX-border,inputY-border):zoomto(inputWidth+border*2,inputHeight+border*2):halign(0):valign(0):diffuse(color("#00000099")) - end; -} - -t[#t+1] = Def.Quad{ - InitCommand=function(self) - self:xy(outputX-border,outputY-border):zoomto(outputWidth+border*2,outputHeight+border*2):halign(0):valign(0):diffuse(color("#00000099")) - end; -} - -return t \ No newline at end of file diff --git a/BGAnimations/_cursor.lua b/BGAnimations/_cursor.lua index 7c490ede..47cb4a85 100644 --- a/BGAnimations/_cursor.lua +++ b/BGAnimations/_cursor.lua @@ -7,10 +7,10 @@ local curIndex = 0 function cursorClick(index) return LoadActor(THEME:GetPathG("","_circle")) .. { - Name="CursorClick"; + Name="CursorClick", InitCommand=function(self) self:diffusealpha(0) - end; + end, MouseLeftClickMessageCommand=function(self) if index == curIndex then self:finishtweening() @@ -21,12 +21,12 @@ function cursorClick(index) self:diffusealpha(0) self:zoom(1) end - end; + end } end local t = Def.ActorFrame{ - Name="Cursor"; + Name="Cursor" } for i=0,maxChild do @@ -34,32 +34,32 @@ for i=0,maxChild do end t[#t+1] = Def.Quad{ - Name="Cursor"; + Name="Cursor", InitCommand=function(self) self:xy(0,0):zoomto(4,4):rotationz(45) - end; + end, MouseLeftClickMessageCommand=function(self) curIndex = (curIndex+1)%20 end -}; +} local function Update(self) t.InitCommand=function(self) self:SetUpdateFunction(Update) - end; + end if not GHETTOGAMESTATE:isWindowed() then self:GetChild("Cursor"):xy(INPUTFILTER:GetMouseX(),INPUTFILTER:GetMouseY()) self:GetChild("Cursor"):visible(true) else self:GetChild("Cursor"):visible(false) - end; + end return false -end; +end t.InitCommand=function(self) self:SetUpdateFunction(Update) -end; +end return t \ No newline at end of file diff --git a/BGAnimations/_fadelong.lua b/BGAnimations/_fadelong.lua index 47713d13..8cafb718 100644 --- a/BGAnimations/_fadelong.lua +++ b/BGAnimations/_fadelong.lua @@ -3,10 +3,10 @@ local t = Def.ActorFrame{} t[#t+1] = Def.Quad{ InitCommand=function(self) self:FullScreen():diffuse(getMainColor("background")):diffusealpha(0) - end; + end, OnCommand=function(self) self:sleep(2):smooth(2):diffusealpha(1) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/_fadeout.lua b/BGAnimations/_fadeout.lua index 38286d64..1ca99dc2 100644 --- a/BGAnimations/_fadeout.lua +++ b/BGAnimations/_fadeout.lua @@ -3,10 +3,10 @@ local t = Def.ActorFrame{} t[#t+1] = Def.Quad{ InitCommand=function(self) self:FullScreen():diffuse(getMainColor("background")):diffusealpha(0) - end; + end, OnCommand=function(self) self:smooth(2):diffusealpha(1) - end; + end } return t \ No newline at end of file diff --git a/BGAnimations/_frame.lua b/BGAnimations/_frame.lua index 1a09323f..cd67c9ee 100644 --- a/BGAnimations/_frame.lua +++ b/BGAnimations/_frame.lua @@ -1,6 +1,6 @@ local t = Def.ActorFrame{} -t[#t+1] = StandardDecorationFromFileOptional("Header","Header"); -t[#t+1] = StandardDecorationFromFileOptional("Footer","Footer"); +t[#t+1] = StandardDecorationFromFileOptional("Header","Header") +t[#t+1] = StandardDecorationFromFileOptional("Footer","Footer") return t \ No newline at end of file diff --git a/BGAnimations/_gameplaydensitygraph.lua b/BGAnimations/_gameplaydensitygraph.lua new file mode 100644 index 00000000..c012c173 --- /dev/null +++ b/BGAnimations/_gameplaydensitygraph.lua @@ -0,0 +1,148 @@ +local cdg + +local optionalParam = Var("width") + +-- hurrrrr nps quadzapalooza -mina +local wodth = capWideScale(280, 300) +if optionalParam ~= nil then + wodth = optionalParam +end +local hidth = 40 +local txtoff = 10 + +local textonleft = true +local function textmover(self) + if isOver(self:GetChild("npstext")) and textonleft then + self:GetChild("npstext"):x(wodth-txtoff):halign(1) + textonleft = false + elseif isOver(self:GetChild("npstext")) and not textonleft then + self:GetChild("npstext"):x(txtoff):halign(0) + textonleft = true + end +end + +local function makeABar(vertices, x, y, barWidth, barHeight, prettycolor) + vertices[#vertices + 1] = {{x,y-barHeight,0},prettycolor} + vertices[#vertices + 1] = {{x-barWidth,y-barHeight,0},prettycolor} + vertices[#vertices + 1] = {{x-barWidth,y,0},prettycolor} + vertices[#vertices + 1] = {{x,y,0},prettycolor} +end + +local function getColorForDensity(density, ncol) + if density == 1 then + return color(".75,.75,.75") -- nps color + elseif density == ncol then + return color(".1,.1,.1") -- biggest chord color + elseif density == 2 then + return color(".5,.5,.5") -- jumps color + elseif density == 3 then + return color(".25,.25,.25") -- hands color + --else + --local c = lerp(density / (ncol +1 ), .1, .75) -- im sure we can programmatically handle n columns but im too lazy + --return color(c..","..c..","..c..","..c) -- to make this look nice atm -mina + end +end + +local function updateGraphMultiVertex(parent, realgraph) + local steps = GAMESTATE:GetCurrentSteps(PLAYER_1) + if steps then + local ncol = steps:GetNumColumns() + local rate = math.max(1, getCurRateValue()) + local graphVectors = steps:GetCDGraphVectors(rate) + if graphVectors == nil then + -- reset everything if theres nothing to show + realgraph:SetVertices({}) + realgraph:SetDrawState( {Mode = "DrawMode_Quads", First = 0, Num = 0} ) + return + end + + local npsVector = graphVectors[1] -- refers to the cps vector for 1 (tap notes) + local numberOfColumns = #npsVector + local columnWidth = wodth/numberOfColumns * rate + + -- set height scale of graph relative to the max nps + local hodth = 0 + for i=1,#npsVector do + if npsVector[i] * 2 > hodth then + hodth = npsVector[i] * 2 + end + end + + parent:GetChild("npsline"):y(-hidth * 0.7) + parent:GetChild("npstext"):settext(hodth / 2 * 0.7 .. "nps"):y(-hidth * 0.9) + hodth = hidth/hodth + local verts = {} -- reset the vertices for the graph + local yOffset = 0 -- completely unnecessary, just a Y offset from the graph + for density = 1,ncol do + for column = 1,numberOfColumns do + if graphVectors[density][column] > 0 then + local barColor = getColorForDensity(density, ncol) + makeABar(verts, math.min(column * columnWidth, wodth), yOffset, columnWidth, graphVectors[density][column] * 2 * hodth, barColor) + end + end + end + + realgraph:SetVertices(verts) + realgraph:SetDrawState( {Mode = "DrawMode_Quads", First = 1, Num = #verts} ) + end +end + +local t = Def.ActorFrame { + Name = "ChordDensityGraph", + InitCommand=function(self) + self:SetUpdateFunction(textmover) + cdg = self + end, + CurrentSongChangedMessageCommand = function(self) + self:diffusealpha(0) + end, + DelayedChartUpdateMessageCommand = function(self) + self:queuecommand("GraphUpdate") + end, + CurrentRateChangedMessageCommand = function(self) + if self:IsVisible() then + self:queuecommand("GraphUpdate") + end + end, + ChartPreviewOnMessageCommand = function(self) + self:queuecommand("GraphUpdate") + end, + Def.Quad { + Name = "cdbg", + InitCommand = function(self) + self:zoomto(wodth, hidth + 2):valign(1):diffuse(color("1,1,1,1")):halign(0) + end + } +} + +t[#t+1] = + Def.ActorMultiVertex { + Name = "CDGraphDrawer", + GraphUpdateCommand = function(self) + if self:IsVisible() then + updateGraphMultiVertex(cdg, self) + self:GetParent():linear(0.3) + self:GetParent():diffusealpha(1) + end + end + } + +-- down here for draw order +t[#t + 1] = Def.Quad { + Name = "npsline", + InitCommand = function(self) + self:zoomto(wodth, 2):diffusealpha(1):valign(1):diffuse(color(".75,0,0,0.75")):halign(0) + end, + +} + +t[#t + 1] = LoadFont("Common Normal") .. { + Name = "npstext", + InitCommand = function(self) + self:halign(0) + self:zoom(0.4) + self:settext(""):diffuse(color("1,0,0")) + end +} + +return t diff --git a/BGAnimations/_lobbyuserlist.lua b/BGAnimations/_lobbyuserlist.lua new file mode 100644 index 00000000..d2bf78eb --- /dev/null +++ b/BGAnimations/_lobbyuserlist.lua @@ -0,0 +1,84 @@ +local usersZoom = 0.45 +local usersWidth = 50 +local usersWidthSmall = 25 +local usersWidthZoom = 50 * (1 / usersZoom) +local usersWidthSmallZoom = 25 * (1 / usersZoom) +local usersRowSize = 4 +local usersX = SCREEN_WIDTH / 4 +local usersY = SCREEN_TOP + 13 +local usersHeight = 10 + +local lobbos +local top = SCREENMAN:GetTopScreen() +local qty = 0 +local posit = getMainColor("positive") +local negat = getMainColor("negative") +local enable = getMainColor("enabled") +local r = + Def.ActorFrame { + BeginCommand = function(self) + self:queuecommand("Set") + end, + InitCommand = function(self) + self:queuecommand("Set") + end, + SetCommand = function(self) + top = SCREENMAN:GetTopScreen() + lobbos = NSMAN:GetLobbyUserList() + end, + UsersUpdateMessageCommand = function(self) + self:queuecommand("Set") + end +} + +local function userLabel(i) + local x = usersX + usersWidth * ((i-1) % usersRowSize) + local y = usersY + math.floor((i-1) / usersRowSize) * usersHeight + local aux = + LoadFont("Common Normal") .. + { + Name = i, + BeginCommand = function(self) + self:xy(x, y):zoom(usersZoom):diffuse(posit):queuecommand("Set") + end, + SetCommand = function(self) + if SCREENMAN:GetTopScreen():GetName() ~= "ScreenNetRoom" then + return + end + local num = self:GetName() + 0 + if num <= #lobbos then + -- if top:GetUserState(num) == 2 or top:GetUserState(num) == 1 then + -- self:diffuse(posit) + -- elseif top:GetUserState(num) == 4 then + -- self:diffuse(negat) + -- else + -- self:diffuse(enable) + -- end + self:settext(lobbos[num]) + else + self:settext("") + end + if qty < 9 then + self:maxwidth(usersWidthZoom) + else + self:maxwidth(usersWidthSmallZoom) + end + end, + PlayerJoinedMessageCommand = function(self) + self:queuecommand("Set") + end, + PlayerUnjoinedMessageCommand = function(self) + self:queuecommand("Set") + end, + UsersUpdateMessageCommand = function(self) + self:queuecommand("Set") + end + } + return aux +end + +for i = 1, 32 do + r[#r + 1] = userLabel(i) +end + +return r diff --git a/BGAnimations/_mouse.lua b/BGAnimations/_mouse.lua index a383736b..eed87d67 100644 --- a/BGAnimations/_mouse.lua +++ b/BGAnimations/_mouse.lua @@ -1,4 +1,5 @@ local top +local whee -- Actor for handling most mouse interactions. local function input(event) @@ -11,6 +12,55 @@ local function input(event) end end + local mouseX = INPUTFILTER:GetMouseX() + local mouseY = INPUTFILTER:GetMouseY() + + if whee and mouseX > capWideScale(370, 500) and mouseX < SCREEN_WIDTH - 32 then + if event.DeviceInput.button == "DeviceButton_left mouse button" and event.type == "InputEventType_FirstPress" then + local n = 0 + local m = 1 + if mouseY > 212 and mouseY < 264 then + m = 0 + elseif mouseY > 264 and mouseY < 312 then + m = 1 + n = 1 + elseif mouseY > 312 and mouseY < 360 then + m = 1 + n = 2 + elseif mouseY > 360 and mouseY < 408 then + m = 1 + n = 3 + elseif mouseY > 408 and mouseY < 456 then + m = 1 + n = 4 + elseif mouseY > 456 and mouseY < 500 then + m = 1 + n = 5 + elseif mouseY > 164 and mouseY < 212 then + m = -1 + n = 1 + elseif mouseY > 112 and mouseY < 164 then + m = -1 + n = 2 + elseif mouseY > 68 and mouseY < 112 then + m = -1 + n = 3 + elseif mouseY > 20 and mouseY < 68 then + m = -1 + n = 4 + elseif mouseY > -30 and mouseY < 20 then + m = -1 + n = 5 + end + + local type = whee:MoveAndCheckType(m * n) + whee:Move(0) + if m == 0 then + top:SelectCurrent(0) + end + end + end + return false end @@ -19,26 +69,27 @@ local t = Def.ActorFrame{ OnCommand = function(self) BUTTON:resetPressedActors() - for _, pn in pairs({PLAYER_1, PLAYER_2}) do - SCREENMAN:set_input_redirected(pn, false) - end + SCREENMAN:set_input_redirected(PLAYER_1, false) top = SCREENMAN:GetTopScreen() + if top:GetName() == "ScreenSelectMusic" or top:GetName() == "ScreenNetSelectMusic" or top:GetName() == "ScreenNetRoom" then + whee = top:GetMusicWheel() + end top:AddInputCallback(input) - end; + end, OffCommand = function(self) BUTTON:resetPressedActors() - end; + end, MouseLeftClickMessageCommand = function(self) self:queuecommand("PlayTopPressedActor") - end; + end, MouseRightClickMessageCommand = function(self) self:queuecommand("PlayTopPressedActor") - end; + end, PlayTopPressedActorCommand = function(self) BUTTON:playTopPressedActor() BUTTON:resetPressedActors() - end; + end, ExitScreenMessageCommand = function(self, params) if params.screen == top:GetName() then top:StartTransitioningScreen("SM_GoToPrevScreen") diff --git a/BGAnimations/_particles.lua b/BGAnimations/_particles.lua index 1eaa7e02..1e2627ad 100644 --- a/BGAnimations/_particles.lua +++ b/BGAnimations/_particles.lua @@ -12,7 +12,7 @@ local function isInScreen(particle) local x = particle:GetX() local y = particle:GetY() return (x > -100-half and x < SCREEN_WIDTH+100+half) and (y > 0-half and y < SCREEN_HEIGHT+half) -end; +end local function resetPosition(particle) particle:x(math.random(0,SCREEN_WIDTH)) @@ -20,14 +20,14 @@ local function resetPosition(particle) --particle:y(math.random(0,SCREEN_HEIGHT)) particle:rotationz(math.random()*360) return -end; +end local posX = {SCREEN_WIDTH,0} local posY = {SCREEN_HEIGHT,0} local function makeParticle(index) return Def.Quad{ - Name="Particle"..index; + Name="Particle"..index, BeginCommand=function (self) self:sleep(index*0.1) local size = math.random(20,50) @@ -40,19 +40,19 @@ local function makeParticle(index) alpha[index] = math.random()*4 self:diffusealpha(alpha[index]) self:queuecommand('Move') - end; + end, MoveCommand = function(self,params) self:finishtweening() self:addy(dy[index]*((SCREEN_CENTER_Y-self:GetY())/2000)) if self:GetDiffuseAlpha() <= 0 then self:sleep(1) self:queuecommand('ResetPosition') - end; + end self:diffusealpha(clamp(alpha[index],0,0.8)) self:sleep(1/200) self:queuecommand('Move') alpha[index] = alpha[index] - 0.005 - end; + end, ResetPositionCommand = function(self) alpha[index] = math.random()*2+2 dy[index] = math.random()*10+1 @@ -61,18 +61,18 @@ local function makeParticle(index) self:x(math.random(0,SCREEN_WIDTH)) self:y(SCREEN_HEIGHT) self:queuecommand('Move') - end; - }; -end; + end + } +end if enabled then for i=1,particleAmount do - t[#t+1] = makeParticle(i); + t[#t+1] = makeParticle(i) dx[#dx+1] = 0 dy[#dy+1] = 0 alpha[#alpha+1] = 0 - end; -end; + end +end return t \ No newline at end of file diff --git a/BGAnimations/_songbg.lua b/BGAnimations/_songbg.lua index d2a78dcc..88921ca4 100644 --- a/BGAnimations/_songbg.lua +++ b/BGAnimations/_songbg.lua @@ -2,7 +2,7 @@ local magnitude = 0.03 local maxDistX = SCREEN_WIDTH*magnitude local maxDistY = SCREEN_HEIGHT*magnitude -local enabled = themeConfig:get_data().global.SongBGEnabled and not(GAMESTATE:IsCourseMode()) +local enabled = themeConfig:get_data().global.SongBGEnabled local moveBG = themeConfig:get_data().global.SongBGMouseEnabled and enabled local brightness = 0.3 @@ -14,19 +14,19 @@ local function getPosX() offset = math.abs(offset) if offset > 1 then offset = math.min(2*math.sqrt(math.abs(offset)),maxDistX) - end; + end else neg = false offset = math.abs(offset) if offset > 1 then offset = math.min(2*math.sqrt(math.abs(offset)),maxDistX) - end; - end; + end + end if neg then return SCREEN_CENTER_X+offset else return SCREEN_CENTER_X-offset - end; + end end local function getPosY() @@ -37,19 +37,19 @@ local function getPosY() offset = math.abs(offset) if offset > 1 then offset = math.min(2*math.sqrt(offset),maxDistY) - end; + end else neg = false offset = math.abs(offset) if offset > 1 then offset = math.min(2*math.sqrt(offset),maxDistY) - end; - end; + end + end if neg then return SCREEN_CENTER_Y+offset else return SCREEN_CENTER_Y-offset - end; + end end local t = Def.ActorFrame{} @@ -57,52 +57,52 @@ local t = Def.ActorFrame{} if enabled then t[#t+1] = Def.ActorFrame{ - Name="MouseXY"; + Name="MouseXY", Def.Sprite { OnCommand=function(self) self:smooth(0.5):diffusealpha(0):queuecommand("ModifySongBackground") - end; + end, CurrentSongChangedMessageCommand=function(self) self:stoptweening():smooth(0.5):diffusealpha(0):queuecommand("ModifySongBackground") - end; + end, ModifySongBackgroundCommand=function(self) self:finishtweening() if GAMESTATE:GetCurrentSong() then local song = GAMESTATE:GetCurrentSong() if song:HasBackground() then - self:visible(true); + self:visible(true) self:LoadBackground(song:GetBackgroundPath()) if moveBG then - self:scaletocover(0-maxDistY/8,0-maxDistY/8,SCREEN_WIDTH+maxDistX/8,SCREEN_BOTTOM+maxDistY/8); + self:scaletocover(0-maxDistY/8,0-maxDistY/8,SCREEN_WIDTH+maxDistX/8,SCREEN_BOTTOM+maxDistY/8) else - self:scaletocover(0,0,SCREEN_WIDTH,SCREEN_BOTTOM); - end; + self:scaletocover(0,0,SCREEN_WIDTH,SCREEN_BOTTOM) + end self:smooth(0.5) self:diffusealpha(brightness) - end; + end else - self:visible(false); - end; - end; + self:visible(false) + end + end, OffCommand=function(self) self:smooth(0.5):diffusealpha(0) end - }; + } } -end; +end local function Update(self) t.InitCommand=function(self) self:SetUpdateFunction(Update) - end; + end self:GetChild("MouseXY"):xy(getPosX()-SCREEN_CENTER_X,getPosY()-SCREEN_CENTER_Y) -end; +end if moveBG then t.InitCommand=function(self) self:SetUpdateFunction(Update) - end; -end; + end +end return t diff --git a/BGAnimations/_userlist.lua b/BGAnimations/_userlist.lua new file mode 100644 index 00000000..965da4cc --- /dev/null +++ b/BGAnimations/_userlist.lua @@ -0,0 +1,99 @@ +local usersZoom = 0.45 +local usersWidth = 50 +local usersWidthSmall = 25 +local usersWidthZoom = 50 * (1 / usersZoom) +local usersWidthSmallZoom = 25 * (1 / usersZoom) +local usersRowSize = 4 +local usersX = SCREEN_WIDTH / 4 +local usersY = SCREEN_TOP + 13 +local usersHeight = 10 + +local top = SCREENMAN:GetTopScreen() +local qty = 0 +local posit = getMainColor("positive") +local negat = getMainColor("negative") +local enable = getMainColor("enabled") +local disabled = getMainColor("disabled") +local highlight = getMainColor("highlight") + +local r = + Def.ActorFrame { + BeginCommand = function(self) + self:queuecommand("Set") + end, + InitCommand = function(self) + self:queuecommand("Set") + end, + SetCommand = function(self) + top = SCREENMAN:GetTopScreen() + end, + UsersUpdateMessageCommand = function(self) + self:queuecommand("Set") + end +} + +local function userLabel(i) + local x = usersX + usersWidth * ((i-1) % usersRowSize) + local y = usersY + math.floor((i-1) / usersRowSize) * usersHeight + local aux = + LoadFont("Common Normal") .. + { + Name = i, + BeginCommand = function(self) + self:xy(x, y):zoom(usersZoom):diffuse(posit):queuecommand("Set") + end, + SetCommand = function(self) + if SCREENMAN:GetTopScreen():GetName() ~= "ScreenNetSelectMusic" then + return + end + local num = self:GetName() + 0 + qty = top:GetUserQty() + if num <= qty then + local str = "" + str = str .. top:GetUser(num) + self:settext(str) + local state = top:GetUserState(num) + if state == 3 then + -- eval + self:diffuse(posit) + elseif state == 2 then + -- playing + self:diffuse(disabled) + elseif state == 4 then + -- options + self:diffuse(highlight) + else -- 1 == can play + local ready = top:GetUserReady(num) + if ready then + self:diffuse(enable) + else + self:diffuse(negat) + end + end + else + self:settext("") + end + if qty < 9 then + self:maxwidth(usersWidthZoom) + else + self:maxwidth(usersWidthSmallZoom) + end + end, + PlayerJoinedMessageCommand = function(self) + self:queuecommand("Set") + end, + PlayerUnjoinedMessageCommand = function(self) + self:queuecommand("Set") + end, + UsersUpdateMessageCommand = function(self) + self:queuecommand("Set") + end + } + return aux +end + +for i = 1, 32 do + r[#r + 1] = userLabel(i) +end + +return r diff --git a/Graphics/ComboGraph Backing.lua b/Graphics/ComboGraph Backing.lua index 21d9ce58..6fe68cbc 100644 --- a/Graphics/ComboGraph Backing.lua +++ b/Graphics/ComboGraph Backing.lua @@ -1,5 +1,5 @@ return Def.Quad{ InitCommand=function(self) self:setsize(1,8):diffuse(color("#333333CC")) - end; -}; \ No newline at end of file + end +} \ No newline at end of file diff --git a/Graphics/ComboGraph ComboNumber.lua b/Graphics/ComboGraph ComboNumber.lua index 42f92278..2cf22eaa 100644 --- a/Graphics/ComboGraph ComboNumber.lua +++ b/Graphics/ComboGraph ComboNumber.lua @@ -1,5 +1,5 @@ return LoadFont("Common normal") .. { InitCommand=function(self) self:zoom(0.35):diffuse(color("#FFFFFF")) - end; -}; \ No newline at end of file + end +} \ No newline at end of file diff --git a/Graphics/ComboGraph NormalCombo.lua b/Graphics/ComboGraph NormalCombo.lua index 97913585..1d226016 100644 --- a/Graphics/ComboGraph NormalCombo.lua +++ b/Graphics/ComboGraph NormalCombo.lua @@ -1,5 +1,5 @@ return Def.Quad{ InitCommand=function(self) self:setsize(1,8):diffuse(getMainColor('highlight')):diffusealpha(0.7) - end; -}; \ No newline at end of file + end +} \ No newline at end of file diff --git a/Graphics/ComboGraphP1 MaxCombo.lua b/Graphics/ComboGraphP1 MaxCombo.lua index fe6bc6de..00b17682 100644 --- a/Graphics/ComboGraphP1 MaxCombo.lua +++ b/Graphics/ComboGraphP1 MaxCombo.lua @@ -1,8 +1,8 @@ return Def.Quad{ InitCommand=function(self) self:setsize(1,8):diffuse(getMainColor('highlight')) - end; + end, BeginCommand=function(self) self:glowshift():effectcolor1(color("1,1,1,0.325")):effectcolor2(color("1,1,1,0")) - end; -}; \ No newline at end of file + end +} \ No newline at end of file diff --git a/Graphics/ComboGraphP2 MaxCombo.lua b/Graphics/ComboGraphP2 MaxCombo.lua index f2d80387..0307c797 100644 --- a/Graphics/ComboGraphP2 MaxCombo.lua +++ b/Graphics/ComboGraphP2 MaxCombo.lua @@ -1,8 +1,8 @@ return Def.Quad{ InitCommand=function(self) self:setsize(1,8):diffuse(getMainColor('highlight')):diffusetopedge(Saturation(Brightness(getMainColor('highlight'),1),0.5)) - end; + end, BeginCommand=function(self) self:glowshift():effectcolor1(color("1,1,1,0.325")):effectcolor2(color("1,1,1,0")) - end; -}; \ No newline at end of file + end +} \ No newline at end of file diff --git a/Graphics/GraphDisplay backing.lua b/Graphics/GraphDisplay backing.lua index d4a49788..887aff83 100644 --- a/Graphics/GraphDisplay backing.lua +++ b/Graphics/GraphDisplay backing.lua @@ -1,5 +1,5 @@ return Def.Quad{ InitCommand=function(self) self:setsize(50,80):diffuse(color("#999999")):diffusealpha(0.7):diffusetopedge(color("#00000033")) - end; -}; \ No newline at end of file + end +} \ No newline at end of file diff --git a/Graphics/MusicWheel highlight.lua b/Graphics/MusicWheel highlight.lua index 4fead135..07f1a728 100644 --- a/Graphics/MusicWheel highlight.lua +++ b/Graphics/MusicWheel highlight.lua @@ -1,23 +1,22 @@ return Def.ActorFrame{ Def.Quad{ - Name="Horizontal"; + Name="Horizontal", InitCommand = function(self) self:x(-4):zoomto(capWideScale(get43size(348),348),52):halign(0) - self:diffuseramp(); + self:diffuseramp() self:effectperiod(1) - self:effectcolor1(color("#FFFFFF00")); - self:effectcolor2(Alpha(getMainColor("highlight"),0.2)); - end; + self:effectcolor1(color("#FFFFFF00")) + self:effectcolor2(Alpha(getMainColor("highlight"),0.2)) + end, SetCommand=function(self) if GAMESTATE:GetCurrentSteps(GAMESTATE:GetEnabledPlayers()[1]) then - self:effectcolor2(Alpha(getDifficultyColor(GAMESTATE:GetHardestStepsDifficulty()),0.2)); + self:effectcolor2(Alpha(getDifficultyColor(GAMESTATE:GetHardestStepsDifficulty()),0.2)) else - self:effectcolor2(Alpha(getMainColor("highlight"),0.2)); + self:effectcolor2(Alpha(getMainColor("highlight"),0.2)) end - end; - CurrentStepsP1ChangedMessageCommand = function(self) self:queuecommand('Set') end; - CurrentStepsP2ChangedMessageCommand = function(self) self:queuecommand('Set') end; - }; + end, + CurrentStepsP1ChangedMessageCommand = function(self) self:queuecommand('Set') end + } -}; \ No newline at end of file +} \ No newline at end of file diff --git a/Graphics/MusicWheelItem SectionCollapsed NormalPart.lua b/Graphics/MusicWheelItem SectionCollapsed NormalPart.lua index d5d2e3af..a7424294 100644 --- a/Graphics/MusicWheelItem SectionCollapsed NormalPart.lua +++ b/Graphics/MusicWheelItem SectionCollapsed NormalPart.lua @@ -7,13 +7,13 @@ t[#t+1] = Def.Quad{ self:x(0) self:zoomto(capWideScale(get43size(340),340),44) self:halign(0) - end; + end, SetCommand = function(self) self:diffuse(getMainColor("frame")) self:diffusealpha(0.9) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - OffCommand = function(self) self:visible(false) end; + end, + BeginCommand = function(self) self:queuecommand('Set') end, + OffCommand = function(self) self:visible(false) end } @@ -23,9 +23,9 @@ t[#t+1] = Def.Quad{ self:zoomto(2,32) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.MusicWheelDivider)) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - OffCommand = function(self) self:visible(false) end; + end, + BeginCommand = function(self) self:queuecommand('Set') end, + OffCommand = function(self) self:visible(false) end } return t diff --git a/Graphics/MusicWheelItem SectionExpanded NormalPart.lua b/Graphics/MusicWheelItem SectionExpanded NormalPart.lua index bc9e8c4c..d104c714 100644 --- a/Graphics/MusicWheelItem SectionExpanded NormalPart.lua +++ b/Graphics/MusicWheelItem SectionExpanded NormalPart.lua @@ -7,13 +7,13 @@ t[#t+1] = Def.Quad{ self:x(0) self:zoomto(capWideScale(get43size(340),340),44) self:halign(0) - end; + end, SetCommand = function(self) self:diffuse(getMainColor("frame")) self:diffusealpha(0.8) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - OffCommand = function(self) self:visible(false) end; + end, + BeginCommand = function(self) self:queuecommand('Set') end, + OffCommand = function(self) self:visible(false) end } @@ -23,9 +23,9 @@ t[#t+1] = Def.Quad{ self:zoomto(2,32) self:halign(0) self:diffuse(color(colorConfig:get_data().selectMusic.MusicWheelDivider)) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - OffCommand = function(self) self:visible(false) end; + end, + BeginCommand = function(self) self:queuecommand('Set') end, + OffCommand = function(self) self:visible(false) end } return t diff --git a/Graphics/MusicWheelItem Song NormalPart.lua b/Graphics/MusicWheelItem Song NormalPart.lua index 5441ee65..d5d1deb5 100644 --- a/Graphics/MusicWheelItem Song NormalPart.lua +++ b/Graphics/MusicWheelItem Song NormalPart.lua @@ -3,10 +3,10 @@ local top local t = Def.ActorFrame{ OnCommand = function(self) top = SCREENMAN:GetTopScreen() - end; + end, SetCommand = function(self,params) self:name(tostring(params.Index)) - end; + end } @@ -15,8 +15,8 @@ t[#t+1] = Def.Quad{ self:x(0) self:zoomto(capWideScale(get43size(340),340),44) self:halign(0) - self:zwrite(true):clearzbuffer(true):blend('BlendMode_NoEffect'); - end; + self:zwrite(true):clearzbuffer(true):blend('BlendMode_NoEffect') + end } t[#t+1] = quadButton(1) .. { @@ -25,47 +25,11 @@ t[#t+1] = quadButton(1) .. { self:zoomto(capWideScale(get43size(340),340),44) self:halign(0) self:visible(false) - end; + end, TopPressedCommand = function(self, params) - if params.input ~= "DeviceButton_left mouse button" then - return - end - - local newIndex = tonumber(self:GetParent():GetName()) - local wheel = top:GetMusicWheel() - local size = wheel:GetNumItems() - local move = newIndex-wheel:GetCurrentIndex() - - if math.abs(move)>math.floor(size/2) then - if newIndex > wheel:GetCurrentIndex() then - move = (move)%size-size - else - move = (move)%size - end - end - - local wheelType = wheel:MoveAndCheckType(move) - wheel:Move(0) - - -- TODO: play sounds. - if move == 0 then - if wheelType == 'WheelItemDataType_Section' then - if wheel:GetSelectedSection() == curFolder then - wheel:SetOpenSection("") - curFolder = "" - else - wheel:SetOpenSection(wheel:GetSelectedSection()) - curFolder = wheel:GetSelectedSection() - end - else - top:SelectCurrent(0) - end - end - - - - end; + + end } t[#t+1] = Def.Quad{ @@ -73,49 +37,36 @@ t[#t+1] = Def.Quad{ self:x(0) self:zoomto(capWideScale(get43size(340),340),44) self:halign(0) - end; + end, SetCommand = function(self) self:name("Wheel"..tostring(self:GetParent():GetName())) self:diffuse(ColorLightTone(getMainColor("frame"))) self:diffusealpha(0.8) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - OffCommand = function(self) self:visible(false) end; -} - - -t[#t+1] = Def.Quad{ - InitCommand= function(self) - self:x(30) - self:zoomto(2,32) - self:halign(0) - self:diffuse(color(colorConfig:get_data().selectMusic.MusicWheelDivider)) - end; - - BeginCommand = function(self) self:queuecommand('Set') end; - OffCommand = function(self) self:visible(false) end; + end, + BeginCommand = function(self) self:queuecommand('Set') end, + OffCommand = function(self) self:visible(false) end } if themeConfig:get_data().global.BannerWheel then - t[#t+1] = Def.Banner{ + t[#t+1] = Def.Sprite { InitCommand = function(self) self:fadeleft(1) self:halign(1) self:x(capWideScale(get43size(340),340)) self:diffusealpha(0.3) self:ztest(true):ztestmode('ZTestMode_WriteOnFail') - end; + end, SetMessageCommand = function(self,params) local song = params.Song - local course = params.Course - if song and not course then - self:LoadFromSong(params.Song) - self:scaletocover(0,-22,capWideScale(get43size(340),340),22) - elseif course and not song then - self:LoadFromCourse(params.Course) - self:scaletocover(0,-22,capWideScale(get43size(340),340),22) + local bnpath = nil + if song then + bnpath = params.Song:GetBannerPath() + if bnpath then + self:LoadBackground(bnpath) + self:scaletocover(0,-22,capWideScale(get43size(340),340),22) + end end - end; + end } end @@ -124,7 +75,7 @@ t[#t+1] = LoadFont("Common Normal") .. { self:xy(340-5,-22+5) self:halign(1) self:zoom(0.3) - end; + end, SetMessageCommand = function(self,params) local song = params.Song @@ -140,8 +91,8 @@ t[#t+1] = LoadFont("Common Normal") .. { end self:diffuse(getSongLengthColor(seconds)) end - end; -}; + end +} t[#t+1] = LoadActor("round_star") .. { InitCommand = function(self) @@ -149,7 +100,7 @@ t[#t+1] = LoadActor("round_star") .. { self:zoom(0.25) self:wag() self:diffuse(Color.Yellow) - end; + end, SetMessageCommand = function(self,params) local song = params.Song self:visible(false) @@ -158,7 +109,7 @@ t[#t+1] = LoadActor("round_star") .. { self:visible(true) end end - end; + end } return t diff --git a/Graphics/MusicWheelItem Sort NormalPart.lua b/Graphics/MusicWheelItem Sort NormalPart.lua index 233fec78..5020f86c 100644 --- a/Graphics/MusicWheelItem Sort NormalPart.lua +++ b/Graphics/MusicWheelItem Sort NormalPart.lua @@ -7,13 +7,13 @@ t[#t+1] = Def.Quad{ self:x(0) self:zoomto(capWideScale(get43size(340),340),44) self:halign(0) - end; + end, SetCommand = function(self) self:diffuse(getMainColor("frame")) self:diffusealpha(0.9) - end; - BeginCommand = function(self) self:queuecommand('Set') end; - OffCommand = function(self) self:visible(false) end; + end, + BeginCommand = function(self) self:queuecommand('Set') end, + OffCommand = function(self) self:visible(false) end } diff --git a/Graphics/MusicWheelItem grades.lua b/Graphics/MusicWheelItem grades.lua index 7485e183..b83ee8b2 100644 --- a/Graphics/MusicWheelItem grades.lua +++ b/Graphics/MusicWheelItem grades.lua @@ -1,28 +1,38 @@ return Def.ActorFrame{ LoadFont("Common Bold") .. { - InitCommand=function(self) - self:xy(16,-1):zoom(0.5):maxwidth(WideScale(get43size(20),20)/0.5) - end; - SetGradeCommand=function(self,params) - local player = params.PlayerNumber - local song = params.Song - local sGrade = params.Grade or 'Grade_None'; - if GAMESTATE:GetNumPlayersEnabled() == 2 then - if player == PLAYER_1 then - self:valign(1) - self:y(-5) - elseif player == PLAYER_2 then - self:valign(0) - self:y(3) - else - self:valign(0.5) - self:y(-1) - end; - else + InitCommand=function(self) + self:xy(16,-1):zoom(0.5):maxwidth(WideScale(get43size(20),20)/0.5) + end, + SetGradeCommand=function(self,params) + local player = params.PlayerNumber + local song = params.Song + local sGrade = params.Grade or 'Grade_None' self:valign(0.5) - end; - self:settext(THEME:GetString("Grade",ToEnumShortString(sGrade)) or "") - self:diffuse(getGradeColor(sGrade)) - end; - }; + self:settext(THEME:GetString("Grade",ToEnumShortString(sGrade)) or "") + self:diffuse(getGradeColor(sGrade)) + end + }, + Def.Quad{ + InitCommand= function(self) + self:x(30) + self:zoomto(2,32) + self:halign(0) + self:diffuse(color(colorConfig:get_data().selectMusic.MusicWheelDivider)) + end, + + BeginCommand = function(self) self:queuecommand('Set') end, + OffCommand = function(self) self:visible(false) end, + SetCommand = function(self, params) + if params.Song then + local goalType = GHETTOGAMESTATE:getLowestGoalTypeBySong(params.Song) + if goalType == 0 then -- No goals + self:diffusebottomedge(color(colorConfig:get_data().selectMusic.MusicWheelDivider)) + elseif goalType == 1 then -- Unfinished goals + self:diffusebottomedge(color(colorConfig:get_data().selectMusic.UnfinishedGoalGradient)) + elseif goalType == 2 then -- All goals are finished + self:diffusebottomedge(color(colorConfig:get_data().selectMusic.CompletedGoalGradient)) + end + end + end + } } \ No newline at end of file diff --git a/Graphics/Notefield board.lua b/Graphics/Notefield board.lua index 8d142989..5c80b0d7 100644 --- a/Graphics/Notefield board.lua +++ b/Graphics/Notefield board.lua @@ -5,7 +5,7 @@ local function ScreenFilter() return Def.Quad{ InitCommand = function(self) self:visible(false) - end; + end, PlayerStateSetCommand = function(self,param) local pn = param.PlayerNumber local style = GAMESTATE:GetCurrentStyle(pn) @@ -28,64 +28,48 @@ end local function LaneHighlight() local t = Def.ActorFrame{} local alpha = 0.4 - local pn - local judgeThreshold = Enum.Reverse(TapNoteScore)[playerConfig:get_data(pn_to_profile_slot(pn)).CBHighlightMinJudge] + local judgeThreshold = Enum.Reverse(TapNoteScore)[playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CBHighlightMinJudge] - for i=1,16 do + local style = GAMESTATE:GetCurrentStyle(PLAYER_1) + local width = style:GetWidth(PLAYER_1) + local cols = style:ColumnsPerPlayer() + local colWidth = width/cols + local reverse = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingReverse() + local receptor = reverse and THEME:GetMetric("Player", "ReceptorArrowsYStandard") or THEME:GetMetric("Player", "ReceptorArrowsYReverse") + local border = 4 + + for i=1,cols do t[#t+1] = Def.Quad{ InitCommand = function(self) self:visible(false) - end; + end, PlayerStateSetCommand = function(self,param) - pn = param.PlayerNumber - - local style = GAMESTATE:GetCurrentStyle(pn) - local width = style:GetWidth(pn) - local cols = style:ColumnsPerPlayer() - local colWidth = width/cols - local enabled = playerConfig:get_data(pn_to_profile_slot(pn)).CBHighlight - local reverse = GAMESTATE:GetPlayerState(pn):GetCurrentPlayerOptions():UsingReverse() - local receptor = reverse and THEME:GetMetric("Player", "ReceptorArrowsYStandard") or THEME:GetMetric("Player", "ReceptorArrowsYReverse") - local border = 4 - - if i > cols or not enabled then - self:visible(false) - self:hibernate(math.huge) - end - self:SetWidth(colWidth-border) self:SetHeight(SCREEN_HEIGHT) self:diffusealpha(alpha) self:xy((i-(cols/2)-(1/2))*colWidth,-receptor) self:fadebottom(0.6):fadetop(0.6) self:visible(false) - end; + end, JudgmentMessageCommand=function(self,params) - local enabled = playerConfig:get_data(pn_to_profile_slot(pn)).CBHighlight - if not enabled then - self:visible(false) - self:hibernate(math.huge) - return - end - local notes = params.Notes local firstTrack = params.FirstTrack+1 - if params.Player == pn and params.TapNoteScore then + if params.TapNoteScore then local enum = Enum.Reverse(TapNoteScore)[params.TapNoteScore] if enum < judgeThreshold and enum > 3 and i == firstTrack then - self:stoptweening(); - self:visible(true); - self:diffuse(color(colorConfig:get_data().judgment[params.TapNoteScore])); + self:stoptweening() + self:visible(true) + self:diffuse(color(colorConfig:get_data().judgment[params.TapNoteScore])) self:diffusealpha(alpha) self:easeIn(0.25) self:diffusealpha(0) - end; + end end - end; + end } end @@ -94,6 +78,10 @@ end t[#t+1] = ScreenFilter() -t[#t+1] = LaneHighlight() + +local highlightEnabled = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CBHighlight +if highlightEnabled then + t[#t+1] = LaneHighlight() +end return t \ No newline at end of file diff --git a/Graphics/OffsetGraph.lua b/Graphics/OffsetGraph.lua index 9c31689b..6d146174 100644 --- a/Graphics/OffsetGraph.lua +++ b/Graphics/OffsetGraph.lua @@ -4,97 +4,303 @@ local W5Window = PREFSMAN:GetPreference("TimingWindowSecondsW5") -- Timing windo local dotWidth = 2 local dotHeight = 2 +-- shamelessly lifted straight from Til Death in Etterna .64: +local judges = {"marv", "perf", "great", "good", "boo", "miss"} +local tst = ms.JudgeScalers +local judge = GetTimingDifficulty() +local tso = tst[judge] + +local enabledCustomWindows = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomEvaluationWindowTimings +judge = enabledCustomWindows and 0 or judge +local customWindowsData = timingWindowConfig:get_data() +local customWindows = customWindowsData.customWindows +local customWindow +local maxOffset = math.max(180, 180 * tso) + + +local dvt = {} -- offset vector +local nrt = {} -- noterow vector +local ctt = {} -- track vector +local ntt = {} -- tap note type vector +local wuab = {} -- time corrected tap notes (?) +local columns = 4 -- the number of columns because we dont keep track of this i guess +local finalSecond = GAMESTATE:GetCurrentSong(PLAYER_1):GetLastSecond() +local td = GAMESTATE:GetCurrentSteps(PLAYER_1):GetTimingData() + +local handspecific = false +local left = false +local setWidth = 0 +local setHeight = 0 +local setSong +local setSteps + +local function fitX(x) -- Scale time values to fit within plot width. + if finalSecond == 0 then + return 0 + end + return x / finalSecond * setWidth - setWidth / 2 +end + +local function fitY(y) -- Scale offset values to fit within plot height + return -1 * y / maxOffset * setHeight / 2 +end +local function setOffsetVerts(vt, x, y, c, alpha) + vt[#vt + 1] = {{x - dotWidth/2, y + dotWidth/2, 0}, c} + vt[#vt + 1] = {{x + dotWidth/2, y + dotWidth/2, 0}, c} + vt[#vt + 1] = {{x + dotWidth/2, y - dotWidth/2, 0}, c} + vt[#vt + 1] = {{x - dotWidth/2, y - dotWidth/2, 0}, c} +end +----- + +local baralpha = 0.4 + local t = Def.ActorFrame{ InitCommand = function(self) self:RunCommandsOnChildren(function(self) - local params = {width = 0, height = 0, song = nil, steps = nil, noterow = {}, offset = {}} + local params = {width = 0, height = 0, song = nil, steps = nil, nrv = {}, dvt = {}, ctt = {}, ntt = {}} self:playcommand("Update", params) end ) - end; + end, + OffsetPlotModificationMessageCommand = function(self, params) + if enabledCustomWindows then + if params.Name == "PrevJudge" then + judge = judge < 2 and #customWindows or judge - 1 + customWindow = customWindowsData[customWindows[judge]] + elseif params.Name == "NextJudge" then + judge = judge == #customWindows and 1 or judge + 1 + customWindow = customWindowsData[customWindows[judge]] + end + elseif params.Name == "PrevJudge" and judge > 1 then + judge = judge - 1 + tso = tst[judge] + elseif params.Name == "NextJudge" and judge < 9 then + judge = judge + 1 + tso = tst[judge] + elseif params.Name == "ToggleHands" and #ctt > 0 then --super ghetto toggle -mina + if not handspecific then + handspecific = true + left = true + elseif handspecific and left then + left = false + elseif handspecific and not left then + handspecific = false + end + end + if params.Name == "ResetJudge" then + judge = enabledCustomWindows and 0 or GetTimingDifficulty() + tso = tst[GetTimingDifficulty()] + end + maxOffset = (enabledCustomWindows and judge ~= 0) and customWindow.judgeWindows.boo or math.max(180, 180 * tso) + MESSAGEMAN:Broadcast("JudgeDisplayChanged") + end } +-- Plot BG t[#t+1] = Def.Quad{ Name = "Background", InitCommand = function(self) self:halign(0):valign(0) self:diffuse(getMainColor("frame")):diffusealpha(0.8) - end; + end, UpdateCommand = function(self, params) + setWidth = params.width + setHeight = params.height + setSong = params.song + setSteps = params.steps + dvt = params.dvt + nrv = params.nrv + ctt = params.ctt + ntt = params.ntt + columns = params.columns self:zoomto(params.width, params.height) - end; + end } +-- Plot center horizontal line t[#t+1] = Def.Quad{ Name = "Center Line", InitCommand = function(self) self:halign(0):valign(0) - self:diffusealpha(0.4) - end; + self:diffusealpha(baralpha) + end, UpdateCommand = function(self, params) self:xy(0,params.height/2) self:zoomto(params.width,1) - end; + end } +local function checkParams(params) + local fixedparams = params + if params.width == nil then + fixedparams = {width = setWidth, + height = setHeight, + song = setSong, + steps = setSteps, + nrv = nrv, + dvt = dvt, + ctt = ctt, + ntt = ntt, + columns = columns} + end + return fixedparams +end + +-- this section creates the bars for different judgment levels +local fantabars = {22.5, 45, 90, 135} +local bantafars = {"TapNoteScore_W2", "TapNoteScore_W3", "TapNoteScore_W4", "TapNoteScore_W5"} +for i = 1, #fantabars do + t[#t + 1] = + Def.Quad { + InitCommand = function(self) + self:halign(0):valign(0) + end, + UpdateCommand = function(self, params) + params = checkParams(params) + self:zoomto(params.width, 1):diffuse(byJudgment(bantafars[i])):diffusealpha(baralpha) + local fit = (enabledCustomWindows and judge ~= 0) and customWindow.judgeWindows[judges[i]] or tso * fantabars[i] + self:y(fitY(fit) + params.height/2) + end, + JudgeDisplayChangedMessageCommand = function(self) + self:queuecommand("Update") + end + } + t[#t + 1] = + Def.Quad { + InitCommand = function(self) + self:halign(0):valign(0) + end, + UpdateCommand = function(self, params) + params = checkParams(params) + self:zoomto(params.width, 1):diffuse(byJudgment(bantafars[i])):diffusealpha(baralpha) + local fit = (enabledCustomWindows and judge ~= 0) and customWindow.judgeWindows[judges[i]] or tso * fantabars[i] + self:y(fitY(-fit) + params.height/2) + end, + JudgeDisplayChangedMessageCommand = function(self) + self:queuecommand("Update") + end + } +end + +-- Late ms text t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:zoom(0.3):halign(0):valign(0):diffusealpha(0.4) end, UpdateCommand = function(self) self:xy(5,5) - self:settextf("Early (-%d ms)", timingWindowScale*W5Window*1000) + self:settextf("Late (+%d ms)", maxOffset) + end, + JudgeDisplayChangedMessageCommand = function(self) + self:queuecommand("Update") end } +-- Early ms text t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:zoom(0.3):halign(0):valign(1):diffusealpha(0.4) end, UpdateCommand = function(self, params) + params = checkParams(params) self:xy(5,params.height-5) - self:settextf("Late (+%d ms)", timingWindowScale*W5Window*1000) + self:settextf("Early (-%d ms)", maxOffset) + end, + JudgeDisplayChangedMessageCommand = function(self) + self:queuecommand("Update") end } +-- Highlight info text +t[#t+1] = LoadFont("Common Normal") .. { + InitCommand = function(self) + self:zoom(0.3):diffusealpha(0.4) + self:settext("") + end, + UpdateCommand = function(self, params) + params = checkParams(params) + self:xy(params.width/2, params.height - 10) + if ntt ~= nil and #ntt > 0 then + if handspecific then + if left then + self:settext("Highlighting left hand taps") + else + self:settext("Highlighting right hand taps") + end + else + self:settext("Down toggles highlights") + end + else + self:settext("") + end + end, + JudgeDisplayChangedMessageCommand = function(self) + self:queuecommand("Update") + end +} + +-- the dots. t[#t+1] = Def.ActorMultiVertex{ UpdateCommand = function(self, params) + params = checkParams(params) local verts = {} - if params.song == nil or params.steps == nil or params.noterow == nil or params.offset == nil then + + if params.song == nil or params.steps == nil or params.nrv == nil or params.dvt == nil then self:SetVertices(verts) self:SetDrawState{Mode="DrawMode_Quads", First = 1, Num = #verts} return end + for i = 1, #params.nrv do + wuab[i] = td:GetElapsedTimeFromNoteRow(params.nrv[i]) + end + local songLength = params.song:GetLastSecond() - for i=1, #params.noterow do - local timestamp = params.steps:GetTimingData():GetElapsedTimeFromNoteRow(params.noterow[i]) - local offset = params.offset[i]/1000 + for i=1, #params.nrv do + if params.dvt[i] ~= nil then + local timestamp = params.steps:GetTimingData():GetElapsedTimeFromNoteRow(params.nrv[i]) + local offset = params.dvt[i]/1000 - local color = offsetToJudgeColor(offset) -- WHY MULTIPLY BY 1000 IF WE NEED IT DIVIDED BY 1000 AGAIN + local color = + (enabledCustomWindows and judge ~= 0) and customOffsetToJudgeColor(params.dvt[i], customWindow.judgeWindows) or + offsetToJudgeColor(params.dvt[i], tst[judge]) - local x = (timestamp/songLength) * params.width - local y = (offset/W5Window/2/timingWindowScale) * params.height + (params.height/2) + local x = fitX(wuab[i]) + params.width / 2 + local y = fitY(params.dvt[i]) + params.height / 2 + --local x = (timestamp/songLength) * params.width + --local y = (offset/W5Window/2/timingWindowScale) * params.height + (params.height/2) + local alpha = 1 -- 1 is the default, 0.3 is the non highlight version - if math.abs(offset) > (W5Window * timingWindowScale) then - -- Misses - verts[#verts+1] = {{x-dotWidth/2, params.height,0}, Alpha(color, 0.3)} - verts[#verts+1] = {{x+dotWidth/2, params.height,0}, Alpha(color, 0.3)} - verts[#verts+1] = {{x+dotWidth/2, 0,0}, Alpha(color, 0.3)} - verts[#verts+1] = {{x-dotWidth/2, 0,0}, Alpha(color, 0.3)} - else - -- Everything else - verts[#verts+1] = {{x-dotWidth/2,y+dotHeight/2,0}, color} - verts[#verts+1] = {{x+dotWidth/2,y+dotHeight/2,0}, color} - verts[#verts+1] = {{x+dotWidth/2,y-dotHeight/2,0}, color} - verts[#verts+1] = {{x-dotWidth/2,y-dotHeight/2,0}, color} - end + if handspecific and left then + if ctt[i] < math.floor(columns / 2) then + alpha = 0.1 + end + elseif handspecific then + if ctt[i] >= math.floor(columns / 2) then + alpha = 0.1 + end + end + if math.abs(offset) >= 1 then + -- Misses + if alpha == 1 then alpha = 0.3 else alpha = 0.1 end + verts[#verts+1] = {{x-dotWidth/4, params.height,0}, Alpha(color, alpha)} + verts[#verts+1] = {{x+dotWidth/4, params.height,0}, Alpha(color, alpha)} + verts[#verts+1] = {{x+dotWidth/4, 0,0}, Alpha(color, alpha)} + verts[#verts+1] = {{x-dotWidth/4, 0,0}, Alpha(color, alpha)} + else + -- Everything else + setOffsetVerts(verts, x, y, Alpha(color, alpha)) + end + end end self:SetVertices(verts) self:SetDrawState{Mode="DrawMode_Quads", First = 1, Num = #verts} - end; + end, + JudgeDisplayChangedMessageCommand = function(self) + self:queuecommand("Update") + end } diff --git a/Graphics/Player combo/default.lua b/Graphics/Player combo/default.lua index bb0a417b..f02f39fc 100644 --- a/Graphics/Player combo/default.lua +++ b/Graphics/Player combo/default.lua @@ -1,150 +1,165 @@ -local c; -local player = Var "Player"; -local bareBone = isBareBone() -local ghostType = playerConfig:get_data(pn_to_profile_slot(player)).GhostScoreType -- 0 = off, 1 = DP, 2 = PS, 3 = MIGS -local avgScoreType = playerConfig:get_data(pn_to_profile_slot(player)).AvgScoreType-- 0 = off, 1 = DP, 2 = PS, 3 = MIGS -local target = playerConfig:get_data(pn_to_profile_slot(player)).GhostTarget/100; -- target score from 0% to 100%. - - -local ShowComboAt = THEME:GetMetric("Combo", "ShowComboAt"); -local Pulse = THEME:GetMetric("Combo", "PulseCommand"); -local PulseLabel = THEME:GetMetric("Combo", "PulseLabelCommand"); - -local NumberMinZoom = THEME:GetMetric("Combo", "NumberMinZoom"); -local NumberMaxZoom = THEME:GetMetric("Combo", "NumberMaxZoom"); -local NumberMaxZoomAt = THEME:GetMetric("Combo", "NumberMaxZoomAt"); - -local LabelMinZoom = THEME:GetMetric("Combo", "LabelMinZoom"); -local LabelMaxZoom = THEME:GetMetric("Combo", "LabelMaxZoom"); +local allowedCustomization = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay +local c +local player = Var "Player" +local wordsOn = themeConfig:get_data().global.ComboWords + + +local ShowComboAt = THEME:GetMetric("Combo", "ShowComboAt") +local Pulse = function(self, param) + self:stoptweening() + self:zoom(1.125 * param.Zoom * MovableValues.ComboZoom) + self:linear(0.05) + self:zoom(param.Zoom * MovableValues.ComboZoom) +end + +local PulseLabel = function(self, param) + self:stoptweening() + self:zoom(param.LabelZoom * MovableValues.ComboZoom) + self:linear(0.05) + self:zoom(param.LabelZoom * MovableValues.ComboZoom) +end + +local NumberMinZoom = 0.4 -- 1 is 100% size zoom +local NumberMaxZoom = 0.5 -- 1 is 100% size zoom +local NumberMaxZoomAt = 100 -- the combo to be at max zoom +local numberCurrentZoom = NumberMinZoom -- keep track of current zoom for arbitraryfunction + +local LabelMinZoom = 0.75 * 0.75 -- 1 is 100% size zoom +local LabelMaxZoom = 0.75 * 0.75 + +local function arbitraryComboX(value) + c.Label:x(value) + c.Number:x(value - 4) + c.Border:x(value) + end + +local function arbitraryComboZoom(value) + c.Label:zoom(value * LabelMaxZoom) + c.Number:zoom(value * numberCurrentZoom) + if allowedCustomization then + c.Border:playcommand("ChangeWidth", {val = c.Number:GetZoomedWidth() + c.Label:GetZoomedWidth()}) + c.Border:playcommand("ChangeHeight", {val = c.Number:GetZoomedHeight()}) + end +end + +local numFC = getComboColor("NumberFC") +local numPFC = getComboColor("NumberPFC") +local numMFC = getComboColor("NumberMFC") +local numReg = getComboColor("NumberRegular") +local numMiss = getComboColor("NumberMiss") +local labelReg = getComboColor("LabelRegular") +local labelMiss = getComboColor("LabelMiss") +local labelRG = getComboColor("LabelRegularGradient") +local labelMG = getComboColor("LabelMissGradient") local t = Def.ActorFrame { LoadFont( "Combo", "numbers" ) .. { - Name="Number"; - OnCommand = THEME:GetMetric("Combo", "NumberOnCommand"); -- y,240-216-1.5;shadowlength,1;halign,1;valign,1;skewx,-0.125;zoom,0.5; - }; - LoadFont("Common Normal") .. { - Name="Label"; - OnCommand = THEME:GetMetric("Combo", "LabelOnCommand"); -- x,6;y,22.5;shadowlength,1;zoom,0.75;diffusebottomedge,color("0.75,0.75,0.75,1");halign,0;valign,1 - }; - - LoadFont("Common Normal") .. { - Name="GhostScore"; + Name="Number", + InitCommand = function(self) + self:xy(MovableValues.ComboX - 4, MovableValues.ComboY):halign(1):valign(1):skewx(-0.125):visible( + false + ) + end, OnCommand = function(self) - self:xy(48,9):zoom(0.45):halign(0):valign(1):shadowlength(1) - if avgScoreType == 0 then - self:x(7) - end + self:shadowlength(1):halign(1):valign(1):skewx(-0.125) end - }; - + }, LoadFont("Common Normal") .. { - Name="AvgScore"; + Name="Label", + InitCommand = function(self) + self:xy(MovableValues.ComboX, MovableValues.ComboY):diffusebottomedge(labelRG):halign(0):valign( + 1 + ):visible(false) + end, OnCommand = function(self) - self:xy(48,9):zoom(0.45):halign(1):valign(1):shadowlength(1) + self:shadowlength(1):diffusebottomedge(labelRG):halign(0):valign(1) end - }; - + }, InitCommand = function(self) - c = self:GetChildren(); - c.Number:visible(false); - c.Label:visible(false); - c.GhostScore:visible(false) - c.AvgScore:visible(false) + c = self:GetChildren() + c.Number:visible(false) + c.Label:visible(false) self:valign(1) self:draworder(350) - end; - - JudgmentMessageCommand = function(self, param) - local diff = param.WifeDifferential - if diff > 0 then - c.GhostScore:settextf('+%.2f', diff) - c.GhostScore:diffuse(getMainColor('positive')) - elseif diff == 0 then - c.GhostScore:settextf('+%.2f', diff) - c.GhostScore:diffuse(color("#FFFFFF")) - else - c.GhostScore:settextf('-%.2f', (math.abs(diff))) - c.GhostScore:diffuse(getMainColor('negative')) - end; - - local wifePercent = math.max(0, param.WifePercent) - if avgScoreType ~= 0 and avgScoreType ~= nil then - c.AvgScore:settextf("%.2f%%", wifePercent) + if (allowedCustomization) then + Movable.DeviceButton_3.element = c + Movable.DeviceButton_4.element = c + Movable.DeviceButton_3.condition = true + Movable.DeviceButton_4.condition = true + Movable.DeviceButton_3.Border = self:GetChild("Border") + Movable.DeviceButton_3.DeviceButton_left.arbitraryFunction = arbitraryComboX + Movable.DeviceButton_3.DeviceButton_right.arbitraryFunction = arbitraryComboX + Movable.DeviceButton_4.DeviceButton_up.arbitraryFunction = arbitraryComboZoom + Movable.DeviceButton_4.DeviceButton_down.arbitraryFunction = arbitraryComboZoom end - end; + end, + OnCommand = function(self) + if (allowedCustomization) then + c.Label:settext("COMBO") + c.Number:visible(true) + c.Label:visible(wordsOn) + c.Number:settext(1000) + Movable.DeviceButton_3.propertyOffsets = {self:GetTrueX() -6, self:GetTrueY() + c.Number:GetHeight()*1.5} -- centered to screen/valigned + setBorderAlignment(c.Border, 0.5, 1) + end + arbitraryComboZoom(MovableValues.ComboZoom) + end, ComboCommand = function(self, param) - local iCombo = param.Misses or param.Combo; + local iCombo = param.Misses or param.Combo if not iCombo or iCombo < ShowComboAt then - c.Number:visible(false); - c.Label:visible(false); - c.GhostScore:visible(false) - c.AvgScore:visible(false) - return; + c.Number:visible(false) + c.Label:visible(false) + return end - local labeltext = ""; + local labeltext = "" if param.Combo then - labeltext = "COMBO"; + labeltext = "COMBO" else - labeltext = "MISSES"; + labeltext = "MISSES" end - c.Label:settext( labeltext ); + c.Label:settext( labeltext ) - param.Zoom = scale( iCombo, 0, NumberMaxZoomAt, NumberMinZoom, NumberMaxZoom ); - param.Zoom = clamp( param.Zoom, NumberMinZoom, NumberMaxZoom ); + param.Zoom = scale( iCombo, 0, NumberMaxZoomAt, NumberMinZoom, NumberMaxZoom ) + param.Zoom = clamp( param.Zoom, NumberMinZoom, NumberMaxZoom ) - param.LabelZoom = scale( iCombo, 0, NumberMaxZoomAt, LabelMinZoom, LabelMaxZoom ); - param.LabelZoom = clamp( param.LabelZoom, LabelMinZoom, LabelMaxZoom ); + param.LabelZoom = scale( iCombo, 0, NumberMaxZoomAt, LabelMinZoom, LabelMaxZoom ) + param.LabelZoom = clamp( param.LabelZoom, LabelMinZoom, LabelMaxZoom ) - c.Number:visible(true); - c.Label:visible(true); - if ghostType ~= 0 and ghostType ~= nil then - c.GhostScore:visible(true) - - c.GhostScore:finishtweening() - c.GhostScore:diffusealpha(1) - c.GhostScore:sleep(0.25) - c.GhostScore:smooth(0.75) - c.GhostScore:diffusealpha(0) - end + c.Number:visible(true) + c.Label:visible(wordsOn) - if avgScoreType ~= 0 and avgScoreType ~= nil then - c.AvgScore:visible(true) - - c.AvgScore:finishtweening() - c.AvgScore:diffusealpha(1) - c.AvgScore:sleep(0.25) - c.AvgScore:smooth(0.75) - c.AvgScore:diffusealpha(0) - end - - c.Number:settext( string.format("%i", iCombo) ); + c.Number:settext( string.format("%i", iCombo) ) -- FullCombo Rewards if param.FullComboW1 then - c.Number:diffuse(color("#00aeef")); - c.Number:glowshift(); + c.Number:diffuse(numMFC) + c.Number:glowshift() elseif param.FullComboW2 then - c.Number:diffuse(color("#fff568")); - c.Number:glowshift(); + c.Number:diffuse(numPFC) + c.Number:glowshift() elseif param.FullComboW3 then - c.Number:diffuse(color("#a4ff00")); - c.Number:stopeffect(); + c.Number:diffuse(numFC) + c.Number:stopeffect() elseif param.Combo then - c.Number:diffuse(Color("White")); - c.Number:stopeffect(); - c.Label:diffuse(Color("White")):diffusebottomedge(color("0.5,0.5,0.5,1")) + c.Number:diffuse(numReg) + c.Number:stopeffect() + c.Label:diffuse(labelReg):diffusebottomedge(labelRG) else - c.Number:diffuse(color("#ff0000")); - c.Number:stopeffect(); - c.Label:diffuse(Color("Red")):diffusebottomedge(color("0.5,0,0,1")) + c.Number:diffuse(numMiss) + c.Number:stopeffect() + c.Label:diffuse(labelMiss):diffusebottomedge(labelMG) + end + if themeConfig:get_data().global.ComboTween then + -- Pulse + Pulse( c.Number, param ) + PulseLabel( c.Label, param ) end - -- Pulse - Pulse( c.Number, param ); - PulseLabel( c.Label, param ); - end; -}; + numberCurrentZoom = param.Zoom + end, + MovableBorder(0, 0, 1, MovableValues.ComboX, MovableValues.ComboY) +} -return t; +return t diff --git a/Graphics/Player judgment/default.lua b/Graphics/Player judgment/default.lua index 5a8192be..8ef7cd20 100644 --- a/Graphics/Player judgment/default.lua +++ b/Graphics/Player judgment/default.lua @@ -1,72 +1,149 @@ -local c; -local player = Var "Player"; +local allowedCustomization = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay +local c +local player = Var "Player" local bareBone = isBareBone() +local JTDisabled = not judgementTween() +local usingAssets = useAssetsJudgements() + +--[[ +Removed from metrics: +# Things the judgment does when you bang on it. +JudgmentW1Command=shadowlength,0;diffusealpha,1;zoom,1.3;linear,0.05;zoom,1;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0;glowblink;effectperiod,0.05;effectcolor1,color("1,1,1,0");effectcolor2,color("1,1,1,0.25") +JudgmentW2Command=shadowlength,0;diffusealpha,1;zoom,1.3;linear,0.05;zoom,1;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0 +JudgmentW3Command=shadowlength,0;diffusealpha,1;zoom,1.2;linear,0.05;zoom,1;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0; +JudgmentW4Command=shadowlength,0;diffusealpha,1;zoom,1.1;linear,0.05;zoom,1;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0; +JudgmentW5Command=shadowlength,0;diffusealpha,1;zoom,1.0;vibrate;effectmagnitude,4,8,8;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0 +JudgmentMissCommand=shadowlength,0;diffusealpha,1;zoom,1;linear,0.8;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0 +]] local JudgeCmds = { - TapNoteScore_W1 = THEME:GetMetric( "Judgment", "JudgmentW1Command" ); - TapNoteScore_W2 = THEME:GetMetric( "Judgment", "JudgmentW2Command" ); - TapNoteScore_W3 = THEME:GetMetric( "Judgment", "JudgmentW3Command" ); - TapNoteScore_W4 = THEME:GetMetric( "Judgment", "JudgmentW4Command" ); - TapNoteScore_W5 = THEME:GetMetric( "Judgment", "JudgmentW5Command" ); - TapNoteScore_Miss = THEME:GetMetric( "Judgment", "JudgmentMissCommand" ); -}; + TapNoteScore_W1 = function(self) + self:shadowlength(0):diffusealpha(1):zoom(1.3 * MovableValues.JudgeZoom) + self:linear(0.05):zoom(1 * MovableValues.JudgeZoom) + self:sleep(0.8):linear(0.1) + self:zoomx(0.5 * MovableValues.JudgeZoom) + self:zoomy(2 * MovableValues.JudgeZoom) + self:diffusealpha(0) + self:glowblink():effectperiod(0.05):effectcolor1(color("1,1,1,0")):effectcolor2(color("1,1,1,0.25")) + end, + TapNoteScore_W2 = function(self) + self:shadowlength(0):diffusealpha(1):zoom(1.3 * MovableValues.JudgeZoom) + self:linear(0.05):zoom(1 * MovableValues.JudgeZoom) + self:sleep(0.8):linear(0.1) + self:zoomx(0.5 * MovableValues.JudgeZoom) + self:zoomy(2 * MovableValues.JudgeZoom) + self:diffusealpha(0) + end, + TapNoteScore_W3 = function(self) + self:shadowlength(0):diffusealpha(1):zoom(1.2 * MovableValues.JudgeZoom) + self:linear(0.05):zoom(1 * MovableValues.JudgeZoom) + self:sleep(0.8):linear(0.1) + self:zoomx(0.5 * MovableValues.JudgeZoom) + self:zoomy(2 * MovableValues.JudgeZoom) + self:diffusealpha(0) + end, + TapNoteScore_W4 = function(self) + self:shadowlength(0):diffusealpha(1):zoom(1.1 * MovableValues.JudgeZoom) + self:linear(0.05):zoom(1 * MovableValues.JudgeZoom) + self:sleep(0.8):linear(0.1) + self:zoomx(0.5 * MovableValues.JudgeZoom) + self:zoomy(2 * MovableValues.JudgeZoom) + self:diffusealpha(0) + end, + TapNoteScore_W5 = function(self) + self:shadowlength(0):diffusealpha(1):zoom(1.0 * MovableValues.JudgeZoom) + self:vibrate() + self:effectmagnitude(0.01,0.02,0.02) + self:sleep(0.8) + self:linear(0.1) + self:zoomx(0.5 * MovableValues.JudgeZoom) + self:zoomy(2 * MovableValues.JudgeZoom) + self:diffusealpha(0) + end, + TapNoteScore_Miss = function(self) + self:shadowlength(0):diffusealpha(1):zoom(1.0 * MovableValues.JudgeZoom) + self:linear(0.8) + self:sleep(0.8):linear(0.1) + self:zoomx(0.5 * MovableValues.JudgeZoom) + self:zoomy(2 * MovableValues.JudgeZoom) + self:diffusealpha(0) + end +} local TNSFrames = { - TapNoteScore_W1 = 0; - TapNoteScore_W2 = 1; - TapNoteScore_W3 = 2; - TapNoteScore_W4 = 3; - TapNoteScore_W5 = 4; - TapNoteScore_Miss = 5; -}; + TapNoteScore_W1 = 0, + TapNoteScore_W2 = 1, + TapNoteScore_W3 = 2, + TapNoteScore_W4 = 3, + TapNoteScore_W5 = 4, + TapNoteScore_Miss = 5 +} + + +local function judgmentZoom(value) + c.Judgment:zoom(value) + if allowedCustomization then + c.Border:playcommand("ChangeWidth", {val = c.Judgment:GetZoomedWidth()}) + c.Border:playcommand("ChangeHeight", {val = c.Judgment:GetZoomedHeight()}) + end +end + local t = Def.ActorFrame { InitCommand = function(self) self:draworder(350) - end; -}; -t[#t+1] = Def.ActorFrame { - LoadActor(THEME:GetPathG("Judgment","Normal")) .. { - Name="Judgment"; + end, + Def.Sprite { + Texture = usingAssets and "../../../../" .. getAssetPath("judgement") or THEME:GetPathG("Judgment", "Normal"), + Name="Judgment", InitCommand=function(self) - self:pause():visible(false) - end; - OnCommand=THEME:GetMetric("Judgment","JudgmentOnCommand"); + self:pause():visible(false):xy(MovableValues.JudgeX, MovableValues.JudgeY) + end, + OnCommand=THEME:GetMetric("Judgment","JudgmentOnCommand"), ResetCommand=function(self) self:finishtweening():stopeffect():visible(false) - end; - }; - - InitCommand = function(self) + end + }, + OnCommand = function(self) c = self:GetChildren() - end; + judgmentZoom(MovableValues.JudgeZoom) + if allowedCustomization then + Movable.DeviceButton_1.element = c + Movable.DeviceButton_2.element = c + Movable.DeviceButton_1.condition = true + Movable.DeviceButton_2.condition = true + Movable.DeviceButton_2.DeviceButton_up.arbitraryFunction = judgmentZoom + Movable.DeviceButton_2.DeviceButton_down.arbitraryFunction = judgmentZoom + Movable.DeviceButton_1.propertyOffsets = {self:GetTrueX() , self:GetTrueY() - c.Judgment:GetHeight()} -- centered to screen/valigned + end + end, JudgmentMessageCommand=function(self, param) - if param.Player ~= player then return end; - if param.HoldNoteScore then return end; + if param.Player ~= player then return end + if param.HoldNoteScore then return end - local iNumStates = c.Judgment:GetNumStates(); - local iFrame = TNSFrames[param.TapNoteScore]; + local iNumStates = c.Judgment:GetNumStates() + local iFrame = TNSFrames[param.TapNoteScore] - local iTapNoteOffset = param.TapNoteOffset; + local iTapNoteOffset = param.TapNoteOffset if not iFrame then return end if iNumStates == 12 then - iFrame = iFrame * 2; + iFrame = iFrame * 2 if not param.Early then - iFrame = iFrame + 1; + iFrame = iFrame + 1 end end - self:playcommand("Reset"); + self:playcommand("Reset") - c.Judgment:visible( true ); - c.Judgment:setstate( iFrame ); - if not bareBone then - JudgeCmds[param.TapNoteScore](c.Judgment); + c.Judgment:visible( true ) + c.Judgment:setstate( iFrame ) + if not bareBone and not JTDisabled then + JudgeCmds[param.TapNoteScore](c.Judgment) end - end; -}; - + end, + MovableBorder(0, 0, 1, MovableValues.JudgeX, MovableValues.JudgeY) +} -return t; +return t diff --git a/Graphics/ScreenOptions page.lua b/Graphics/ScreenOptions page.lua index dff75f00..caa7f010 100644 --- a/Graphics/ScreenOptions page.lua +++ b/Graphics/ScreenOptions page.lua @@ -4,15 +4,15 @@ t[#t+1] = Def.Quad{ InitCommand = function(self) self:zoomto(SCREEN_WIDTH*0.8,400) self:diffuse(getMainColor("frame")):diffusealpha(0) - end; + end, OnCommand = function(self) self:smooth(0.5) self:diffusealpha(0.8) - end; + end, OffCommand = function(self) self:smooth(0.5) self:diffusealpha(0) - end; + end } return t \ No newline at end of file diff --git a/Graphics/ScreenSelectMusic BPMDisplay.lua b/Graphics/ScreenSelectMusic BPMDisplay.lua index d4b5b690..5c4b2ba7 100644 --- a/Graphics/ScreenSelectMusic BPMDisplay.lua +++ b/Graphics/ScreenSelectMusic BPMDisplay.lua @@ -1,13 +1,12 @@ return Def.BPMDisplay { - File=THEME:GetPathF("BPMDisplay", "bpm"); - Name="BPMDisplay"; + File=THEME:GetPathF("BPMDisplay", "bpm"), + Name="BPMDisplay", InitCommand=function(self) self:horizalign(left):zoom(0.50) - end; - SetCommand=function(self) self:SetFromGameState() end; - CurrentSongChangedMessageCommand = function(self) self:playcommand("Set") end; - CurrentCourseChangedMessageCommand = function(self) self:playcommand("Set") end; - CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end; - CurrentStepsP1ChangedMessageCommand = function(self) self:playcommand("Set") end; - CurrentStepsP2ChangedMessageCommand = function(self) self:playcommand("Set") end; -}; \ No newline at end of file + end, + SetCommand=function(self) self:SetFromGameState() end, + CurrentSongChangedMessageCommand = function(self) self:playcommand("Set") end, + CurrentCourseChangedMessageCommand = function(self) self:playcommand("Set") end, + CurrentRateChangedMessageCommand = function(self) self:playcommand("Set") end, + CurrentStepsP1ChangedMessageCommand = function(self) self:playcommand("Set") end +} \ No newline at end of file diff --git a/Graphics/ScreenSelectMusic BPMLabel.lua b/Graphics/ScreenSelectMusic BPMLabel.lua index 85ed0cf2..008581e1 100644 --- a/Graphics/ScreenSelectMusic BPMLabel.lua +++ b/Graphics/ScreenSelectMusic BPMLabel.lua @@ -1,9 +1,9 @@ return Def.ActorFrame { LoadFont("Common Bold") .. { - Text="BPM"; + Text="BPM", InitCommand=function(self) self:horizalign(right):zoom(0.50) - end; - }; -}; + end + } +} diff --git a/Graphics/ScreenTitleMenu scroll.lua b/Graphics/ScreenTitleMenu scroll.lua index b848172d..32a7c53c 100644 --- a/Graphics/ScreenTitleMenu scroll.lua +++ b/Graphics/ScreenTitleMenu scroll.lua @@ -1,16 +1,16 @@ -local gc = Var("GameCommand"); +local gc = Var("GameCommand") return Def.ActorFrame { LoadFont("Common Normal") .. { - Text=THEME:GetString("ScreenTitleMenu",gc:GetText()); + Text=THEME:GetString("ScreenTitleMenu",gc:GetText()), OnCommand=function(self) self:halign(0):zoom(0.5) - end; + end, GainFocusCommand=function(self) self:diffusealpha(1) - end; + end, LoseFocusCommand=function(self) self:diffusealpha(0.5) - end; - }; -}; \ No newline at end of file + end + } +} \ No newline at end of file diff --git a/Graphics/ScreenWithMenuElements Footer.lua b/Graphics/ScreenWithMenuElements Footer.lua index d5aff371..10ec38db 100644 --- a/Graphics/ScreenWithMenuElements Footer.lua +++ b/Graphics/ScreenWithMenuElements Footer.lua @@ -2,7 +2,11 @@ local screenWithNoTips = { ScreenSelectMusic = true, ScreenMusicInfo = true, ScreenPlayerProfile = true, - ScreenGroupInfo = true, + ScreenNetEvaluation = true, + ScreenNetSelectMusic = true, + ScreenNetRoom = true, + ScreenNetPlayerOptions = true, + ScreenNetMusicInfo = true, } local t = Def.ActorFrame{} @@ -14,34 +18,34 @@ t[#t+1] = quadButton(2) .. { self:valign(1) self:zoomto(SCREEN_WIDTH,height) self:diffuse(getMainColor("frame")):diffusealpha(0.8) - end; + end, OnCommand = function(self) self:zoomy(0) self:easeOut(0.5) self:zoomy(height) - end; + end, OffCommand = function(self) self:easeOut(0.5) self:zoomy(0) - end; + end } t[#t+1] = LoadFont("Common Bold") .. { - Name = "currentTime"; + Name = "currentTime", InitCommand=function(self) self:xy(SCREEN_WIDTH-10,SCREEN_HEIGHT-height/2):zoom(0.45):halign(1) - end; + end, OnCommand = function(self) self:diffuse(color(colorConfig:get_data().main.headerText)) self:y(SCREEN_HEIGHT+height/2) self:easeOut(0.5) self:y(SCREEN_HEIGHT-height/2) - end; + end, OffCommand = function(self) self:easeOut(0.5) self:y(SCREEN_HEIGHT+height/2) - end; -}; + end +} local function Update(self) local year = Year() @@ -51,7 +55,7 @@ local function Update(self) local minute = Minute() local second = Second() self:GetChild("currentTime"):settextf("%04d-%02d-%02d %02d:%02d:%02d",year,month,day,hour,minute,second) -end; +end t.InitCommand=function(self) self:SetUpdateFunction(Update) @@ -61,7 +65,7 @@ if themeConfig:get_data().global.TipType >= 2 then t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:xy(10,SCREEN_HEIGHT-10):zoom(0.4):maxwidth((SCREEN_WIDTH-150)/0.4):halign(0) - end; + end, OnCommand = function(self) self:diffuse(color(colorConfig:get_data().main.headerText)) if not screenWithNoTips[SCREENMAN:GetTopScreen():GetName()] then @@ -70,12 +74,12 @@ if themeConfig:get_data().global.TipType >= 2 then self:y(SCREEN_HEIGHT+height/2) self:easeOut(0.5) self:y(SCREEN_HEIGHT-height/2) - end; + end, OffCommand = function(self) self:easeOut(0.5) self:y(SCREEN_HEIGHT+height/2) end } -end; +end return t \ No newline at end of file diff --git a/Graphics/ScreenWithMenuElements Header.lua b/Graphics/ScreenWithMenuElements Header.lua index 2b30d03c..d85d9520 100644 --- a/Graphics/ScreenWithMenuElements Header.lua +++ b/Graphics/ScreenWithMenuElements Header.lua @@ -5,7 +5,7 @@ local top local t = Def.ActorFrame{ OnCommand = function(self) top = SCREENMAN:GetTopScreen() - end; + end } t[#t+1] = quadButton(3)..{ @@ -14,16 +14,16 @@ t[#t+1] = quadButton(3)..{ self:valign(0) self:zoomto(SCREEN_WIDTH,height) self:diffuse(getMainColor("frame")):diffusealpha(0.8) - end; + end, OnCommand = function(self) self:zoomy(0) self:easeOut(0.5) self:zoomy(height) - end; + end, OffCommand = function(self) self:easeOut(0.5) self:zoomy(0) - end; + end } t[#t+1] = quadButton(4)..{ @@ -32,64 +32,64 @@ t[#t+1] = quadButton(4)..{ self:valign(0):halign(0) self:zoomto(30,height) self:diffuse(getMainColor("frame")):diffusealpha(0.3) - end; + end, OnCommand = function(self) self:zoomy(0) self:easeOut(0.5) self:zoomy(height) - end; + end, OffCommand = function(self) self:easeOut(0.5) self:zoomy(0) - end; + end, TopPressedCommand = function(self, params) if params.input == "DeviceButton_left mouse button" then MESSAGEMAN:Broadcast("ExitScreen",{screen = top:GetName()}) end - end; + end } t[#t+1] = LoadFont("Common Bold")..{ - Name = "HeaderTitle"; - Text = Screen.String("HeaderText"); + Name = "HeaderTitle", + Text = Screen.String("HeaderText"), InitCommand = function (self) self:diffuse(color(colorConfig:get_data().main.headerText)) self:zoom(0.3) self:xy(15,height/2) self:settext("Back") - end; + end, OnCommand = function(self) self:y(-height/2) self:easeOut(0.5) self:y(height/2) - end; + end, OffCommand = function(self) self:easeOut(0.5) self:y(-height/2) - end; -}; + end +} t[#t+1] = LoadFont("Common Bold")..{ - Name = "HeaderTitle"; - Text = Screen.String("HeaderText"); + Name = "HeaderTitle", + Text = Screen.String("HeaderText"), InitCommand = function (self) self:diffuse(color(colorConfig:get_data().main.headerText)) self:zoom(0.5) self:halign(0) self:xy(35,height/2) - end; + end, OnCommand = function(self) self:y(-height/2) self:easeOut(0.5) self:y(height/2) - end; + end, OffCommand = function(self) self:easeOut(0.5) self:y(-height/2) - end; + end, UpdateScreenHeaderMessageCommand = function(self,param) self:settext(param.Header) - end; -}; + end +} return t \ No newline at end of file diff --git a/Graphics/ScrollBar TickThumb.lua b/Graphics/ScrollBar TickThumb.lua new file mode 100644 index 00000000..881c7383 --- /dev/null +++ b/Graphics/ScrollBar TickThumb.lua @@ -0,0 +1,33 @@ +local t = Def.ActorFrame {} +local screname +local whee +t[#t + 1] = + Def.ActorFrame { + Def.Quad { + Name = "DootyMcBooty", + BeginCommand = function(self) + self:zoomto(32, 32):valign(0.634522134234) + screname = SCREENMAN:GetTopScreen():GetName() + if screname == "ScreenSelectMusic" or screname == "ScreenNetSelectMusic" then + whee = SCREENMAN:GetTopScreen():GetMusicWheel() + end + end, + MouseLeftClickMessageCommand = function(self) + screname = SCREENMAN:GetTopScreen():GetName() + if screname == "ScreenSelectMusic" or screname == "ScreenNetSelectMusic" then + if whee then + local mx = SCREEN_WIDTH - INPUTFILTER:GetMouseX() + if mx < 32 and mx > 0 then + local idx = whee:GetCurrentIndex() + local num = whee:GetNumItems() + local dum = (INPUTFILTER:GetMouseY() - 45) / (SCREEN_HEIGHT - 103) + whee:Move(notShit.round(num * dum) - idx) + whee:Move(0) + end + end + end + end + } +} + +return t \ No newline at end of file diff --git a/Graphics/StepsDisplayListRow Autogen.lua b/Graphics/StepsDisplayListRow Autogen.lua index 2b3204e7..c4208d68 100644 --- a/Graphics/StepsDisplayListRow Autogen.lua +++ b/Graphics/StepsDisplayListRow Autogen.lua @@ -1,8 +1,8 @@ return LoadFont("Common Normal") .. { InitCommand=function(self) self:xy(0,0):zoom(0.4):rotationz(90) - end; + end, BeginCommand=function(self) self:settext("Autogen") - end; -}; \ No newline at end of file + end +} \ No newline at end of file diff --git a/Graphics/StepsDisplayListRow StepsType.lua b/Graphics/StepsDisplayListRow StepsType.lua index 7e4d0f2e..4e5d3ee6 100644 --- a/Graphics/StepsDisplayListRow StepsType.lua +++ b/Graphics/StepsDisplayListRow StepsType.lua @@ -1,7 +1,7 @@ local t = LoadFont("Common normal")..{ - InitCommand=function(self) - self:x(30):zoom(0.3):rotationz(90) - end; -}; + InitCommand=function(self) + self:x(30):zoom(0.3):rotationz(90) + end +} -return t; \ No newline at end of file +return t \ No newline at end of file diff --git a/Graphics/StepsDisplayListRow frame.lua b/Graphics/StepsDisplayListRow frame.lua index 950388ab..733ed88c 100644 --- a/Graphics/StepsDisplayListRow frame.lua +++ b/Graphics/StepsDisplayListRow frame.lua @@ -6,15 +6,14 @@ local t = Def.ActorFrame{ t[#t+1] = Def.Quad{ InitCommand=function(self) self:zoomto(60,60):diffuse(getMainColor("frame")):diffusealpha(0.7):rotationz(90) - end; - -}; + end +} t[#t+1] = Def.Quad{ InitCommand=function(self) self:x(-10):zoomto(50,25):diffuse(color("#ffffff")):diffusealpha(0.5):rotationz(90) - end; -}; + end +} diff --git a/Graphics/pause_menu.lua b/Graphics/pause_menu.lua deleted file mode 100644 index d3d3b3ad..00000000 --- a/Graphics/pause_menu.lua +++ /dev/null @@ -1,264 +0,0 @@ -gameplay_pause_count= 0 -course_stopped_by_pause_menu= false - -local pause_buttons= {Start= false, Select= true, Back= true} -local pause_double_tap_time= 1 -local tap_debounce_time= .1 -local pause_press_times= {} -local screen_gameplay= false -local menu_items= {[PLAYER_1]= {}, [PLAYER_2]= {}} -local menu_frames= {} -local menu_choices= { - "continue_playing", - "restart_song", - "forfeit_song", -} -if GAMESTATE:IsCourseMode() then - menu_choices= { - "continue_playing", - "skip_song", - "forfeit_course", - "end_course", - } -end -local menu_spacing= 32 -local menu_bg_width= _screen.w * .4 -local menu_text_width= _screen.w * .35 -local menu_x= {[PLAYER_1]= _screen.w*.25, [PLAYER_2]= _screen.w*.75} -local menu_y= _screen.cy - (#menu_choices * .5 * menu_spacing) -local current_menu_choice= {} -local menu_is_showing= {} -local enabled_players= {} - -local function create_menu_item(pn, x, y, item_name) - - return Def.ActorFrame{ - InitCommand = function(self) - table.insert(menu_items[pn], self) - self:xy(x, y) - end, - Def.Quad{ - Name="Quad", - InitCommand = function(self) - self:zoomto(menu_bg_width,menu_spacing) - self:diffusealpha(0.5) - self:playcommand("LoseFocus") - end, - LoseFocusCommand= function(self) - self:diffusealpha(0.1) - end, - GainFocusCommand= function(self) - self:diffusealpha(0.3) - end, - }, - Def.BitmapText{ - Name="Text", - Font= "Common Normal", Text= THEME:GetString("PauseMenu", item_name), - InitCommand= function(self) - self:playcommand("LoseFocus") - end, - LoseFocusCommand= function(self) - --self:stopeffect():rotationz(0) - self:zoom(1) - end, - GainFocusCommand= function(self) - --self:wag():effectperiod(2):effectmagnitude(0, 0, 5) - self:zoom(1.1) - end, - }, - } -end - -local function create_menu_frame(pn, x, y) - local frame= Def.ActorFrame{ - InitCommand= function(self) - self:xy(x, y):playcommand("Hide") - menu_frames[pn]= self - end, - ShowCommand= function(self) - self:visible(true) - end, - HideCommand= function(self) - self:visible(false) - end, - Def.Quad{ - InitCommand= function(self) - self:setsize(menu_bg_width, menu_spacing * (#menu_choices + 1)) - :y(-menu_spacing):vertalign(0) - :diffuse{0, 0, 0, .25} - :playcommand("Hide") - end, - }, - } - for i, choice in ipairs(menu_choices) do - frame[#frame+1]= create_menu_item(pn, 0, (i-1)*menu_spacing, choice) - end - return frame -end - -local function backout(screen) - screen_gameplay:SetPrevScreenName(screen):begin_backing_out() -end - -local function show_menu(pn) - menu_frames[pn]:playcommand("Show") - for i, item in ipairs(menu_items[pn]) do - item:GetChild("Text"):playcommand("LoseFocus") - item:GetChild("Quad"):playcommand("LoseFocus") - end - current_menu_choice[pn]= 1 - menu_items[pn][current_menu_choice[pn]]:GetChild("Text"):playcommand("GainFocus") - menu_items[pn][current_menu_choice[pn]]:GetChild("Quad"):playcommand("GainFocus") - menu_is_showing[pn]= true -end - -local function close_menu(pn) - menu_frames[pn]:playcommand("Hide") - menu_is_showing[pn]= false - local stay_paused= false - for pn, showing in pairs(menu_is_showing) do - if showing then - stay_paused= true - end - end - if not stay_paused then - local fg= screen_gameplay:GetChild("SongForeground") - if fg then fg:visible(old_fg_visible) end - screen_gameplay:PauseGame(false) - end -end - -local choice_actions= { - continue_playing= function(pn) - close_menu(pn) - end, - restart_song= function(pn) - backout("ScreenStageInformation") - end, - forfeit_song= function(pn) - backout(SelectMusicOrCourse()) - end, - skip_song= function(pn) - screen_gameplay:PostScreenMessage("SM_NotesEnded", 0) - end, - forfeit_course= function(pn) - backout(SelectMusicOrCourse()) - end, - end_course= function(pn) - course_stopped_by_pause_menu= true - screen_gameplay:PostScreenMessage("SM_NotesEnded", 0) - end, -} - -local menu_actions= { - Start= function(pn) - local choice_name= menu_choices[current_menu_choice[pn]] - if choice_actions[choice_name] then - choice_actions[choice_name](pn) - end - end, - Left= function(pn) - if current_menu_choice[pn] > 1 then - menu_items[pn][current_menu_choice[pn]]:playcommand("LoseFocus") - current_menu_choice[pn]= current_menu_choice[pn] - 1 - menu_items[pn][current_menu_choice[pn]]:playcommand("GainFocus") - end - end, - Right= function(pn) - if current_menu_choice[pn] < #menu_choices then - menu_items[pn][current_menu_choice[pn]]:playcommand("LoseFocus") - current_menu_choice[pn]= current_menu_choice[pn] + 1 - menu_items[pn][current_menu_choice[pn]]:playcommand("GainFocus") - end - end, -} -menu_actions.Up= menu_actions.Left -menu_actions.Down= menu_actions.Right -menu_actions.MenuLeft= menu_actions.Left -menu_actions.MenuRight= menu_actions.Right -menu_actions.MenuUp= menu_actions.Up -menu_actions.MenuDown= menu_actions.Down - -local down_status= {} - -local function detect_lr_press() - return down_status.MenuLeft and down_status.MenuRight -end - -local function pause_and_show(pn) - gameplay_pause_count= gameplay_pause_count + 1 - screen_gameplay:PauseGame(true) - local fg= screen_gameplay:GetChild("SongForeground") - if fg then - old_fg_visible= fg:GetVisible() - fg:visible(false) - end - local prompt_text= screen_gameplay:GetChild("Debug") - if prompt_text then - prompt_text:playcommand("TweenOff") - end - show_menu(pn) -end - -local function input(event) - local pn= event.PlayerNumber - if not enabled_players[pn] then return end - local button= event.GameButton - if not button then return end - if event.type == "InputEventType_Release" then - down_status[event.button]= false - return - end - down_status[event.button]= true - if screen_gameplay:GetName() == "ScreenGameplaySyncMachine" then return end - local is_paused= screen_gameplay:IsPaused() - if is_paused then - if menu_is_showing[pn] then - if menu_actions[button] then - menu_actions[button](pn) - return - end - else - if pause_buttons[button] or detect_lr_press() then - show_menu(pn) - return - end - end - else - button= event.button - if event.type ~= "InputEventType_FirstPress" then return end - if detect_lr_press() then - pause_and_show(pn) - elseif pause_buttons[button] then - if GAMESTATE:GetCoinMode() == "CoinMode_Pay" then return end - if pause_press_times[pn] then - local time_since_press= GetTimeSinceStart() - pause_press_times[pn] - if time_since_press > tap_debounce_time then - if time_since_press <= pause_double_tap_time then - pause_and_show(pn) - else - pause_press_times[pn]= GetTimeSinceStart() - end - end - else - pause_press_times[pn]= GetTimeSinceStart() - end - else - pause_press_times[pn]= nil - end - end -end - -local frame= Def.ActorFrame{ - OnCommand= function(self) - screen_gameplay= SCREENMAN:GetTopScreen() - screen_gameplay:AddInputCallback(input) - end, -} - -for i, pn in ipairs(GAMESTATE:GetEnabledPlayers()) do - enabled_players[pn]= true - frame[#frame+1]= create_menu_frame(pn, menu_x[pn], menu_y) -end - -return frame diff --git a/Languages/en.ini b/Languages/en.ini index bf56f0b9..8da2750a 100644 --- a/Languages/en.ini +++ b/Languages/en.ini @@ -1,6 +1,6 @@ [Common] -WindowTitle=StepMania: spawncamping-wallhack -StepMania=StepMania: spawncamping-wallhack +WindowTitle=Etterna: spawncamping-wallhack +StepMania=Etterna: spawncamping-wallhack [CustomDifficulty] Beginner=Beginner @@ -30,6 +30,9 @@ ColorChange =Color Config GitHub=GitHub Repo [OptionNames] +EWMA=EWMA +SetPercent = Set Percent +PersonalBest = Personal Best 50%=50% 55%=55% @@ -53,6 +56,56 @@ GitHub=GitHub Repo 145%=145% 150%=150% + +0.7x=0.7x +0.75x=0.75x +0.8x=0.8x +0.85x=0.85x +0.9x=0.9x +0.95x=0.95x +1=1 +1.0x=1.0x +1.05x=1.05x +1.1x=1.1x +1.15x=1.15x +1.2x=1.2x +1.25x=1.25x +1.3x=1.3x +1.35x=1.35x +1.4x=1.4x +1.45x=1.45x +1.5x=1.5x +1.55x=1.55x +1.6x=1.6x +1.65x=1.65x +1.7x=1.7x +1.75x=1.75x +1.8x=1.8x +1.85x=1.85x +1.9x=1.9x +1.95x=1.95x +2.0x=2.0x +2.05x=2.05x +2.1x=2.1x +2.15x=2.15x +2.2x=2.2x +2.25x=2.25x +2.3x=2.3x +2.35x=2.35x +2.4x=2.4x +2.45x=2.45x +2.5x=2.5x +2.55x=2.55x +2.6x=2.6x +2.65x=2.65x +2.7x=2.7x +2.75x=2.75x +2.8x=2.8x +2.85x=2.85x +2.9x=2.9x +2.95x=2.95x +3.0x=3.0x + [OptionTitles] DefaultScoreType =Default ScoreType TipType =Tip Type @@ -69,10 +122,22 @@ ReceptorSize=Receptor Size SongPreview =Song Preview BannerWheel =Banner Wheel BareBone = BareBone +ComboTween = Combo Animations +ComboWords = Combo Words +JudgementTween = Judgement Animations +UseAssetsJudgements = Native Judgements +EvalScoreboard = Evaluation Scoreboard +DisplayPercent = Display Percent +TargetTracker = Target Tracker +TargetGoal = Target Goal +TargetTrackerMode = Target Tracker Mode +Leaderboard = Gameplay Leaderboard +LeaderboardSlots = Leaderboard Slots +AnimatedLeaderboard = Leaderboard Animations [OptionExplanations] -Avatars=Set Avatars. This is temporary. +Avatars=Set Avatars. DefaultScoreType =Default ScoreType TipType =Sets the Tiptype to either display tips or random quotes and phrases or nothing at all. @@ -89,19 +154,22 @@ NPSWindow =Sets the time window (in seconds) of the NPS Display. Smaller window ReceptorSize=Sets the size of the receptors. MeasureLines=Toggle whether to display measure lines on the notefield. Please reload metrics afterwards. ProgressBar =Determines the location of the progress bar during gameplay. +Leaderboard = Show the leaderboard in gameplay. This option only affects offline play. +LeaderboardSlots = Set the max number of slots that appear on the leaderboard in gameplay. +AnimatedLeaderboard = Toggle animations for when ranks change on the leaderboard in gameplay. -SongPreview =Set how the sample preview of the song is played. +SongPreview = SM Style is the standard preview. Both osu! styles start from song exit. Osu! current loops from the preview start. Osu! old loops from song start. BannerWheel =Show banners on the music wheel. -BareBone = Enables BareBone mode which removes performance-heavy elements in ScreenGameplay. Pacemaker graph, NPS display and GhostScore loading will be disabled. - -[PauseMenu] -continue_playing=Continue Playing -end_course=End Course -forfeit_course=Forfeit Course -forfeit_song=Forfeit Song -pause_count=Pause Count -restart_song=Restart Song -skip_song=Skip Song +BareBone = Simplify some Gameplay elements. +ComboTween = Toggle growth and animations for combo numbers and text. +ComboWords = Toggle the COMBO text on your combo. +JudgementTween = Toggle flashy animations for judgements. +UseAssetsJudgements = Toggle whether or not to use the judgements in the Assets folder or in the theme. +EvalScoreboard = Toggle whether or not to use the new Evaluation Screen Scoreboard. The new one provides access to all online Leaderboard features and has a new look. +DisplayPercent = Show your current Wife percentage. +TargetTracker = Toggle a tracker that shows your current difference in Wifepoints and Percent against a PB or Goal. +TargetGoal = Define a goal percentage for the Target Tracker. +TargetTrackerMode = Set the mode for the Target Tracker. Set Percent uses the goal percentage. Personal Best uses your current rate PB. [OptionTitles] JudgeType=Judge Count @@ -127,16 +195,18 @@ LaneCoverOptions=Lane Cover Options NPSUpdateRate=NPS Graph Update Rate NPSMaxVerts=NPS Graph Max Vertices SaveGhostScore= Save Ghost Score - +CustomizeGameplay=Customize Gameplay +PlayerInfoType = Player Info Type [OptionExplanations] +ScreenFilter=Darkens the area behind the Notefield. JudgeType=Set Judgecount Type -JudgeType=Judge Count +JudgeType=Display current Judgment Count and Grade. No Highlights disables highlighting judgments as they increment. AvgScoreType =Set Scoretype for average score GhostScoreType=Set Scoretype of ghost score GhostTarget=Set target for ghost score -ErrorBar=Enable Error Bar +ErrorBar=Enable the Error Bar. EWMA is an Exponential Weighted Moving Average of recent taps. On just displays all recent taps. ErrorBarOptions=Options relating to the Error Bar ErrorBarDuration=Amount of time it takes each tick to fade out (in seconds). ErrorBarMaxCount=Maximum number of ticks that can be displayed at one point. @@ -155,6 +225,9 @@ NPSDisplayOptions=Options relating to the NPS meter and graph. NPSUpdateRate=Sets how often the NPS graph will update (in seconds). NPSMaxVerts=Sets the maximum number of points the graph will contain. Large values will cause performance issues. SaveGhostScore= Toggle saving of Ghost Score data. +PlayerInfoType = Allow disabling the extra detail of the Player Info Actor in Gameplay. Minimal will reduce it to the lifebar only. + +CustomizeGameplay=Enable customize gameplay. This allows you to move various elements of gameplay. [ScreenEvaluation] HeaderText=Results @@ -180,6 +253,9 @@ HeaderText=Profile [ScreenMusicInfo] HeaderText=Song Info +[ScreenNetMusicInfo] +HeaderText=Song Info + [ScreenGroupInfo] HeaderText=Group Info @@ -192,6 +268,24 @@ HeaderText=Select Avatar [ScreenDownload] HeaderText=Download Packs +[ScreenFiltering] +HeaderText=Song Filtering + +[ScreenFileTagManager] +HeaderText=Manage Tags + +[ScreenChartLeaderboard] +HeaderText=Chart Leaderboards + +[ScreenChartLeaderboard] +HeaderText=Chart Leaderboards + +[ScreenChartPreview] +HeaderText=Chart Preview + +[ScreenGoalManager] +HeaderText=Goal Manager + [ScreenPlaylistInfo] HeaderText=Playlist diff --git a/README.md b/README.md index 81c57c23..f532f769 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,22 @@ # spawncamping-wallhack -A WIP Stepmania 5 theme aimed primarily for KB players. +A SM5 Theme ported for Etterna, a client aimed primarily for KB players. + +Here are some old screenshots (very old) Screenshots -Requirements: See the requirements listed for each release. Otherwise, master branch requires Etterna 0.58 or newer. -sc-wh 2.0.2 will be the final release for vanilla SM5 version(s) unless there's demand for another backport. +See newer screenshots here (latest versions) +Screenshots + +Requirements: The latest release version of Etterna. Older releases are for SM5. --- -### Acknowledgements +# Acknowledgements +### From Prim * The StepMania 5 devs (notably freem and Kyzentun) for making this possible in the first place. * People in #stepmania-devs and the Rhythm gamers discord for feedback. * Some of the theme elements are adapted from the default theme or this by jousway https://github.com/Jousway/Stepmania-Zpawn * Kyzentun's prefs system is used for setting various profile/theme preferences. (which is now available in _fallback for 5.1) +### From Poco +* Everyone, I love this game --- diff --git a/Scripts/00 ThemeInfo.lua b/Scripts/00 ThemeInfo.lua index bd40188e..f2684c5b 100644 --- a/Scripts/00 ThemeInfo.lua +++ b/Scripts/00 ThemeInfo.lua @@ -1,19 +1,19 @@ -- theme identification file themeInfo = { - Name = "spawncamping-wallhack (etterna .58)", - Version = "2.1.0", -- a.b.c, a for complete overhauls, b for major releases, c for minor additions/bugfix. - Date = "20180225", -}; + Name = "spawncamping-wallhack (etterna .65.1)", + Version = "2.2.0", -- a.b.c, a for complete overhauls, b for major releases, c for minor additions/bugfix. + Date = "20190404", +} function getThemeName() return themeInfo["Name"] -end; +end function getThemeVersion() return themeInfo["Version"] -end; +end function getThemeDate() return themeInfo["Date"] -end; +end diff --git a/Scripts/00 Utility.lua b/Scripts/00 Utility.lua index 69a865d2..3f174642 100644 --- a/Scripts/00 Utility.lua +++ b/Scripts/00 Utility.lua @@ -3,29 +3,29 @@ function get43size(size4_3) return 640*(size4_3/854) -end; +end function capWideScale(AR4_3,AR16_9) if AR4_3 < AR16_9 then return clamp(WideScale(AR4_3, AR16_9),AR4_3,AR16_9) else return clamp(WideScale(AR4_3, AR16_9),AR16_9,AR4_3) - end; -end; + end +end --returns if the table contains the key. function tableContains(table,key) return (table[key] ~= nil) -end; +end --for non-array tables. function getTableSize(table) local i = 0 for k,v in pairs(table) do i = i+1 - end; + end return i -end; +end -- returns the hexadecimal representaion of the MD5 hash. function MD5FileHex(sPath) @@ -159,7 +159,7 @@ end -- from profile.lua in til death function easyInputStringWithParams(question, maxLength, isPassword, f, params) - SCREENMAN:AddNewScreenToTop("ScreenTextEntry"); + SCREENMAN:AddNewScreenToTop("ScreenTextEntry") local settings = { Question = question, MaxInputLength = maxLength, @@ -167,8 +167,8 @@ function easyInputStringWithParams(question, maxLength, isPassword, f, params) OnOK = function(answer) f(answer, params) end - }; - SCREENMAN:GetTopScreen():Load(settings); + } + SCREENMAN:GetTopScreen():Load(settings) end function easyInputStringWithFunction(question, maxLength, isPassword, f) diff --git a/Scripts/00 settings_system.lua b/Scripts/00 settings_system.lua deleted file mode 100644 index 89cc2326..00000000 --- a/Scripts/00 settings_system.lua +++ /dev/null @@ -1,240 +0,0 @@ -local settings_prefix= "/" .. THEME:GetThemeDisplayName() .. "_settings/" -global_cur_game= GAMESTATE:GetCurrentGame():GetName():lower() - -function force_table_elements_to_match_type(candidate, must_match, depth_remaining) - for k, v in pairs(candidate) do - if type(must_match[k]) ~= type(v) then - candidate[k]= nil - elseif type(v) == "table" and depth_remaining ~= 0 then - force_table_elements_to_match_type(v, must_match[k], depth_remaining-1) - end - end - for k, v in pairs(must_match) do - if type(candidate[k]) == "nil" then - if type(v) == "table" then - candidate[k]= DeepCopy(v) - else - candidate[k]= v - end - end - end -end - -local function slot_to_prof_dir(slot, reason) - local prof_dir= "Save" - if slot and slot ~= "ProfileSlot_Invalid" then - prof_dir= PROFILEMAN:GetProfileDir(slot) - if not prof_dir or prof_dir == "" then - --Warn("Could not fetch profile dir to " .. reason .. ".") - return - end - end - return prof_dir -end - -local function load_conf_file(fname) - local file= RageFileUtil.CreateRageFile() - local ret= {} - if file:Open(fname, 1) then - local data= loadstring(file:Read()) - setfenv(data, {}) - local success, data_ret= pcall(data) - if success then - ret= data_ret - end - file:Close() - end - file:destroy() - return ret -end - -local setting_mt= { - __index= { - init= function(self, name, file, default, match_depth) - assert(type(default) == "table", "default for setting must be a table.") - self.name= name - self.file= file - self.default= default - self.match_depth= match_depth - self.dirty_table= {} - self.data_set= {} - return self - end, - load= function(self, slot) - slot= slot or "ProfileSlot_Invalid" - local prof_dir= slot_to_prof_dir(slot, "read " .. self.name) - if not prof_dir then - self.data_set[slot]= DeepCopy(self.default) - else - local fname= prof_dir .. settings_prefix .. self.file - if not FILEMAN:DoesFileExist(fname) then - self.data_set[slot]= DeepCopy(self.default) - else - local from_file= load_conf_file(fname) - if type(from_file) == "table" then - if self.match_depth and self.match_depth ~= 0 then - force_table_elements_to_match_type( - from_file, self.default, self.match_depth-1) - end - self.data_set[slot]= from_file - else - self.data_set[slot]= DeepCopy(self.default) - end - end - end - return self.data_set[slot] - end, - get_data= function(self, slot) - slot= slot or "ProfileSlot_Invalid" - return self.data_set[slot] or self.default - end, - set_data= function(self, slot, data) - slot= slot or "ProfileSlot_Invalid" - self.data_set[slot]= data - end, - set_dirty= function(self, slot) - slot= slot or "ProfileSlot_Invalid" - self.dirty_table[slot]= true - end, - check_dirty= function(self, slot) - slot= slot or "ProfileSlot_Invalid" - return self.dirty_table[slot] - end, - clear_slot= function(self, slot) - slot= slot or "ProfileSlot_Invalid" - self.dirty_table[slot]= nil - self.data_set[slot]= nil - end, - save= function(self, slot) - slot= slot or "ProfileSlot_Invalid" - if not self:check_dirty(slot) then return end - local prof_dir= slot_to_prof_dir(slot, "write " .. self.name) - if not prof_dir then return end - local fname= prof_dir .. settings_prefix .. self.file - local file_handle= RageFileUtil.CreateRageFile() - if not file_handle:Open(fname, 2) then - Warn("Could not open '" .. fname .. "' to write " .. self.name .. ".") - else - local output= "return " .. lua_table_to_string(self.data_set[slot]) - file_handle:Write(output) - file_handle:Close() - file_handle:destroy() - end - end, - save_all= function(self) - for slot, data in pairs(self.data_set) do - self:save(slot) - end - end -}} - -function create_setting(name, file, default, match_depth) - return setmetatable({}, setting_mt):init(name, file, default, match_depth) -end - -function write_str_to_file(str, fname, str_name) - local file_handle= RageFileUtil.CreateRageFile() - if not file_handle:Open(fname, 2) then - Warn("Could not open '" .. fname .. "' to write " .. str_name .. ".") - else - file_handle:Write(str) - file_handle:Close() - file_handle:destroy() - end -end - -function string_needs_escape(str) - if str:match("^[a-zA-Z_][a-zA-Z_0-9]*$") then - return false - else - return true - end -end - -function lua_table_to_string(t, indent, line_pos) - indent= indent or "" - line_pos= (line_pos or #indent) + 1 - local internal_indent= indent .. " " - local ret= "{" - local has_table= false - for k, v in pairs(t) do if type(v) == "table" then has_table= true end - end - if has_table then - ret= "{\n" .. internal_indent - line_pos= #internal_indent - end - local separator= "" - local function do_value_for_key(k, v, need_key_str) - if type(v) == "nil" then return end - local k_str= k - if type(k) == "number" then - k_str= "[" .. k .. "]" - else - if string_needs_escape(k) then - k_str= "[" .. ("%q"):format(k) .. "]" - else - k_str= k - end - end - if need_key_str then - k_str= k_str .. "= " - else - k_str= "" - end - local v_str= "" - if type(v) == "table" then - v_str= lua_table_to_string(v, internal_indent, line_pos + #k_str) - elseif type(v) == "string" then - v_str= ("%q"):format(v) - elseif type(v) == "number" then - if v ~= math.floor(v) then - v_str= ("%.6f"):format(v) - local last_nonz= v_str:reverse():find("[^0]") - if last_nonz then - v_str= v_str:sub(1, -last_nonz) - end - else - v_str= tostring(v) - end - else - v_str= tostring(v) - end - local to_add= k_str .. v_str - if type(v) == "table" then - if separator == "" then - to_add= separator .. to_add - else - to_add= separator .."\n" .. internal_indent .. to_add - end - else - if line_pos + #separator + #to_add > 80 then - line_pos= #internal_indent + #to_add - to_add= separator .. "\n" .. internal_indent .. to_add - else - to_add= separator .. to_add - line_pos= line_pos + #to_add - end - end - ret= ret .. to_add - separator= ", " - end - -- do the integer indices from 0 to n first, in order. - do_value_for_key(0, t[0], true) - for n= 1, #t do - do_value_for_key(n, t[n], false) - end - for k, v in pairs(t) do - local is_integer_key= (type(k) == "number") and (k == math.floor(k)) and k >= 0 and k <= #t - if not is_integer_key then - do_value_for_key(k, v, true) - end - end - ret= ret .. "}" - return ret -end - -local slot_conversion= { - [PLAYER_1]= "ProfileSlot_Player1", [PLAYER_2]= "ProfileSlot_Player2",} -function pn_to_profile_slot(pn) - return slot_conversion[pn] or "ProfileSlot_Invalid" -end \ No newline at end of file diff --git a/Scripts/01 avatar_config.lua b/Scripts/01 avatar_config.lua index 8eb952c5..8984bbdc 100644 --- a/Scripts/01 avatar_config.lua +++ b/Scripts/01 avatar_config.lua @@ -4,5 +4,15 @@ local defaultConfig = { }, } + avatarConfig = create_setting("avatarConfig", "avatarConfig.lua", defaultConfig, 0) -avatarConfig:load() \ No newline at end of file +avatarConfig:load() + + +function findAvatar(ID) + if avatarConfig:get_data().avatar[ID] ~= nil then + return avatarConfig:get_data().avatar[ID] + else + return defaultConfig.avatar.default + end +end \ No newline at end of file diff --git a/Scripts/01 color_config.lua b/Scripts/01 color_config.lua index c023bea4..ad5d82e0 100644 --- a/Scripts/01 color_config.lua +++ b/Scripts/01 color_config.lua @@ -4,13 +4,16 @@ local defaultConfig = { frame = "#000000", highlight = "#00AEEF", background = "#FFFFFF", - warning = "#EEBB00"; + warning = "#EEBB00", enabled = "#4CBB17", disabled = "#666666", negative = "#FF9999", positive = "#66ccff", headerText = "#FFFFFF", headerFrameText = "#FFFFFF", + transition = "#888888", + tabFrame = "#333333", + tabButton = "#FFFFFF", }, clearType = { @@ -22,7 +25,7 @@ local defaultConfig = { ClearType_SDG = "#448844", ClearType_FC = "#66cc66", ClearType_MF = "#cc6666", - ClearType_SDCB = "#666666", + ClearType_SDCB = "#33ccff", ClearType_EXHC = "#ff9933", ClearType_HClear = "#ff6666", ClearType_Clear = "#33aaff", @@ -115,6 +118,24 @@ local defaultConfig = { PacemakerCurrent = "#0099FF", }, + combo = { + NumberFC = "#A4FF00", + NumberPFC = "#FFF568", + NumberMFC = "#00AEEF", + NumberRegular = "#DDDDDD", + NumberMiss = "#FF0000", + LabelRegular = "#DDDDDD", + LabelMiss = "#FF2020", + LabelRegularGradient = "#888888", + LabelMissGradient = "#880000" + }, + + leaderboard = { + background = "#111111CC", + border = "#000111", + text = "#9654FD" + }, + evaluation = { BackgroundText = "#000000", ScoreCardText = "#FFFFFF", @@ -129,11 +150,21 @@ local defaultConfig = { MusicWheelArtistText = "#FFFFFF", MusicWheelSectionCountText = "#FFFFFF", MusicWheelDivider = "#FFFFFF", + UnfinishedGoalGradient = "#FF66FF", + CompletedGoalGradient = "#66FF66", MusicWheelExtraColor = "#FFCCCC", ProfileCardText = "#FFFFFF", TabContentText = "#FFFFFF", BannerText = "#FFFFFF", StepsDisplayListText = "#FFFFFF" + }, + + miscellaneous = { + PreviewProgress = "#00FF66", + PreviewSeek = "#FF3333", + ChordGraphGradientDark = "#555555", + TagPositive = "#5555BB", + TagNegative = "#BB5555", } } @@ -156,16 +187,28 @@ function getMainColor(type) return color(colorConfig:get_data().main[type]) end +function getComboColor(type) + return color(colorConfig:get_data().combo[type]) +end + +function getLeaderboardColor(type) + return color(colorConfig:get_data().leaderboard[type]) +end + function getGradeColor (grade) - return color(colorConfig:get_data().grade[grade]) or color(colorConfig:get_data().grade['Grade_None']); + return color(colorConfig:get_data().grade[grade]) or color(colorConfig:get_data().grade['Grade_None']) end function getDifficultyColor(diff) - return color(colorConfig:get_data().difficulty[diff]) or color("#ffffff"); + return color(colorConfig:get_data().difficulty[diff]) or color("#ffffff") end function getPaceMakerColor(type) - return color(colorConfig:get_data().gameplay["Pacemaker"..type]) or color("#ffffff"); + return color(colorConfig:get_data().gameplay["Pacemaker"..type]) or color("#ffffff") +end + +function getMiscColor(type) + return color(colorConfig:get_data().miscellaneous[type]) end function getSongLengthColor(s) @@ -220,11 +263,108 @@ function offsetToJudgeColor(offset) end end +-- expecting ms input (153, 13.321, etc) so convert to seconds to compare to judgment windows -mina +function offsetToJudgeColor(offset, scale) + local offset = math.abs(offset / 1000) + if not scale then + scale = PREFSMAN:GetPreference("TimingWindowScale") + end + if offset <= scale * PREFSMAN:GetPreference("TimingWindowSecondsW1") then + return color(colorConfig:get_data().judgment["TapNoteScore_W1"]) + elseif offset <= scale * PREFSMAN:GetPreference("TimingWindowSecondsW2") then + return color(colorConfig:get_data().judgment["TapNoteScore_W2"]) + elseif offset <= scale * PREFSMAN:GetPreference("TimingWindowSecondsW3") then + return color(colorConfig:get_data().judgment["TapNoteScore_W3"]) + elseif offset <= scale * PREFSMAN:GetPreference("TimingWindowSecondsW4") then + return color(colorConfig:get_data().judgment["TapNoteScore_W4"]) + elseif offset <= math.max(scale * PREFSMAN:GetPreference("TimingWindowSecondsW5"), 0.180) then + return color(colorConfig:get_data().judgment["TapNoteScore_W5"]) + else + return color(colorConfig:get_data().judgment["TapNoteScore_Miss"]) + end +end + +-- 30% hardcoded, should var but lazy atm -mina +function offsetToJudgeColorAlpha(offset, scale) + local offset = math.abs(offset / 1000) + if not scale then + scale = PREFSMAN:GetPreference("TimingWindowScale") + end + if offset <= scale * PREFSMAN:GetPreference("TimingWindowSecondsW1") then + return color(colorConfig:get_data().judgment["TapNoteScore_W1"] .. "48") + elseif offset <= scale * PREFSMAN:GetPreference("TimingWindowSecondsW2") then + return color(colorConfig:get_data().judgment["TapNoteScore_W2"] .. "48") + elseif offset <= scale * PREFSMAN:GetPreference("TimingWindowSecondsW3") then + return color(colorConfig:get_data().judgment["TapNoteScore_W3"] .. "48") + elseif offset <= scale * PREFSMAN:GetPreference("TimingWindowSecondsW4") then + return color(colorConfig:get_data().judgment["TapNoteScore_W4"] .. "48") + elseif offset <= math.max(scale * PREFSMAN:GetPreference("TimingWindowSecondsW5"), 0.180) then + return color(colorConfig:get_data().judgment["TapNoteScore_W5"] .. "48") + else + return color(colorConfig:get_data().judgment["TapNoteScore_Miss"] .. "48") + end +end + +-- 30% hardcoded, should var but lazy atm -mina +function customOffsetToJudgeColor(offset, windows) + local offset = math.abs(offset) + if offset <= windows.marv then + return color(colorConfig:get_data().judgment["TapNoteScore_W1"] .. "48") + elseif offset <= windows.perf then + return color(colorConfig:get_data().judgment["TapNoteScore_W2"] .. "48") + elseif offset <= windows.great then + return color(colorConfig:get_data().judgment["TapNoteScore_W3"] .. "48") + elseif offset <= windows.good then + return color(colorConfig:get_data().judgment["TapNoteScore_W4"] .. "48") + elseif offset <= math.max(windows.boo, 0.180) then + return color(colorConfig:get_data().judgment["TapNoteScore_W5"] .. "48") + else + return color(colorConfig:get_data().judgment["TapNoteScore_Miss"] .. "48") + end +end + function getBorderColor() return HSV(Hour()*360/12, 0.7, 1) end -function TapNoteScoreToColor(tns) return color(colorConfig:get_data().judgment[tns]) or color("#ffffff"); end; +function TapNoteScoreToColor(tns) return color(colorConfig:get_data().judgment[tns]) or color("#ffffff") end + +function byJudgment(judge) + return color(colorConfig:get_data().judgment[judge]) +end + +function byDifficulty(diff) + return color(colorConfig:get_data().difficulty[diff]) +end + +-- i guess if i'm going to use this naming convention it might as well be complete and standardized which means redundancy -mina +function byGrade(grade) + return color(colorConfig:get_data().grade[grade]) or color(colorConfig:get_data().grade["Grade_None"]) +end + +-- Colorized stuff +function byMSD(x) + if x then + return HSV(math.max(95 - (x / 40) * 150, -50), 0.9, 0.9) + end + return HSV(0, 0.9, 0.9) +end + +function byMusicLength(x) + if x then + x = math.min(x, 600) + return HSV(math.max(95 - (x / 900) * 150, -50), 0.9, 0.9) + end + return HSV(0, 0.9, 0.9) +end + +function byFileSize(x) + if x then + x = math.min(x, 600) + return HSV(math.max(95 - (x / 1025) * 150, -50), 0.9, 0.9) + end + return HSV(0, 0.9, 0.9) +end -- a tad-bit desaturated with a wider color range vs til death function getMSDColor(MSD) diff --git a/Scripts/01 player_config.lua b/Scripts/01 player_config.lua index b245cb68..d28986f8 100644 --- a/Scripts/01 player_config.lua +++ b/Scripts/01 player_config.lua @@ -1,30 +1,126 @@ +local defaultGameplayCoordinates = { + JudgeX = 0, + JudgeY = 40, + ComboX = 30, + ComboY = -20, + ErrorBarX = SCREEN_CENTER_X, + ErrorBarY = SCREEN_CENTER_Y + 53, + TargetTrackerX = SCREEN_CENTER_X + 26, + TargetTrackerY = SCREEN_CENTER_Y + 30, + JudgeCounterX = 0, + JudgeCounterY = SCREEN_CENTER_Y - 80, + DisplayPercentX = 80, + DisplayPercentY = SCREEN_CENTER_Y - 92, + NPSDisplayX = 5, + NPSDisplayY = SCREEN_BOTTOM - 170, + NPSGraphX = 0, + NPSGraphY = SCREEN_BOTTOM - 160, + NotefieldX = 0, + NotefieldY = 0, + LeaderboardX = SCREEN_WIDTH - (SCREEN_WIDTH * (IsUsingWideScreen() and 0.275 or 0.25)), + LeaderboardY = 20, + PlayerInfoP1X = 2, + PlayerInfoP1Y = 20, + PracticeCDGraphX = 0, + PracticeCDGraphY = SCREEN_HEIGHT - 35 +} + +local defaultGameplaySizes = { + JudgeZoom = 1.0, + ComboZoom = 0.6, + ErrorBarWidth = 240, + ErrorBarHeight = 10, + TargetTrackerZoom = 0.4, + DisplayPercentZoom = 1, + NPSDisplayZoom = 0.4, + NPSGraphWidth = 1.0, + NPSGraphHeight = 1.0, + NotefieldWidth = 1.0, + NotefieldHeight = 1.0, + LeaderboardWidth = 1.0, + LeaderboardHeight = 1.0, + LeaderboardSpacing = 0.0, + PlayerInfoP1Width = 1.0, + PlayerInfoP1Height = 1.0, + PracticeCDGraphWidth = 0.8, + PracticeCDGraphHeight = 1 +} + local defaultConfig = { --Avatar = "_fallback.png", ScreenFilter = 0, - JudgeType = 0, + JudgeType = 2, -- type for the judge counter AvgScoreType = 0, GhostScoreType = 0, GhostTarget = 0, - ErrorBar = false, + TargetTracker = true, + TargetTrackerMode = 0, + TargetGoal = 93, + ErrorBar = 0, --ErrorBarDuration = 1, --ErrorBarMaxCount = 100, + leaderboardEnabled = false, PaceMaker = false, LaneCover = 0, -- soon to be changed to: 0=off, 1=sudden, 2=hidden LaneCoverHeight = 0, --LaneCoverLayer = 350, -- notefield_draw_order.under_explosions + DisplayPercent = true, NPSDisplay = false, NPSGraph = false, --NPSUpdateRate = 0.1, --NPSMaxVerts = 300, + ReceptorSize = 100, CBHighlight = false, FCEffect = true, Username = "", Password = "", - CBHighlightMinJudge = "TapNoteScore_W4" + CBHighlightMinJudge = "TapNoteScore_W4", + CustomizeGameplay = false, + GameplayXYCoordinates = { + ["4K"] = DeepCopy(defaultGameplayCoordinates), + ["5K"] = DeepCopy(defaultGameplayCoordinates), + ["6K"] = DeepCopy(defaultGameplayCoordinates), + ["7K"] = DeepCopy(defaultGameplayCoordinates), + ["8K"] = DeepCopy(defaultGameplayCoordinates) + }, + GameplaySizes = { + ["4K"] = DeepCopy(defaultGameplaySizes), + ["5K"] = DeepCopy(defaultGameplaySizes), + ["6K"] = DeepCopy(defaultGameplaySizes), + ["7K"] = DeepCopy(defaultGameplaySizes), + ["8K"] = DeepCopy(defaultGameplaySizes) + } } playerConfig = create_setting("playerConfig", "playerConfig.lua", defaultConfig, -1) +local tmp2 = playerConfig.load +playerConfig.load = function(self, slot) + local tmp = force_table_elements_to_match_type + force_table_elements_to_match_type = function() + end + local x = create_setting("playerConfig", "playerConfig.lua", {}, -1) + x = x:load(slot) + local coords = x.GameplayXYCoordinates + local sizes = x.GameplaySizes + if sizes and not sizes["4K"] then + defaultConfig.GameplaySizes["4K"] = sizes + defaultConfig.GameplaySizes["5K"] = sizes + defaultConfig.GameplaySizes["6K"] = sizes + defaultConfig.GameplaySizes["7K"] = sizes + defaultConfig.GameplaySizes["8K"] = sizes + end + if coords and not coords["4K"] then + defaultConfig.GameplayXYCoordinates["4K"] = coords + defaultConfig.GameplayXYCoordinates["5K"] = coords + defaultConfig.GameplayXYCoordinates["6K"] = coords + defaultConfig.GameplayXYCoordinates["7K"] = coords + defaultConfig.GameplayXYCoordinates["8K"] = coords + end + force_table_elements_to_match_type = tmp + return tmp2(self, slot) +end +playerConfig:load() function LoadProfileCustom(profile, dir) local players = GAMESTATE:GetEnabledPlayers() @@ -34,8 +130,8 @@ function LoadProfileCustom(profile, dir) playerProfile = PROFILEMAN:GetProfile(v) if playerProfile:GetGUID() == profile:GetGUID() then pn = v - end; - end; + end + end if pn then playerConfig:load(pn_to_profile_slot(pn)) @@ -50,8 +146,8 @@ function SaveProfileCustom(profile, dir) playerProfile = PROFILEMAN:GetProfile(v) if playerProfile:GetGUID() == profile:GetGUID() then pn = v - end; - end; + end + end if pn then playerConfig:set_dirty(pn_to_profile_slot(pn)) diff --git a/Scripts/01 tags.lua b/Scripts/01 tags.lua new file mode 100644 index 00000000..b1204db5 --- /dev/null +++ b/Scripts/01 tags.lua @@ -0,0 +1,6 @@ +local defaultConfig = { + playerTags = {} +} + +tags = create_setting("tags", "tags.lua", defaultConfig, 0) +tags:load() diff --git a/Scripts/01 theme_config.lua b/Scripts/01 theme_config.lua index efd1bfee..76e88c61 100644 --- a/Scripts/01 theme_config.lua +++ b/Scripts/01 theme_config.lua @@ -7,11 +7,19 @@ local defaultConfig = { Particles = true, RateSort = true, ScoreBoardNag = true, - MeasureLines = true, + MeasureLines = false, ProgressBar = 1, -- 0 = off, 1 bottom , 2 top SongPreview = 3, -- 1 = SM style, 2 = osu! Style (new), 3 = osu! style (old) BannerWheel = true, + UseAssetsJudgements = false, + JudgementTween = true, + ComboTween = true, + ComboWords = true, + LeaderboardSlots = 8, + AnimatedLeaderboard = true, BareBone = false, -- Still can't beat jousway lel + EvalScoreboard = true, + PlayerInfoType = true -- true is full, false is minimal (lifebar only) }, NPSDisplay = { DynamicWindow = false, -- unused @@ -41,3 +49,11 @@ end function isBareBone() return themeConfig:get_data().global.BareBone end + +function judgementTween() + return themeConfig:get_data().global.JudgementTween +end + +function useAssetsJudgements() + return themeConfig:get_data().global.UseAssetsJudgements +end \ No newline at end of file diff --git a/Scripts/01 timing_windows_config.lua b/Scripts/01 timing_windows_config.lua new file mode 100644 index 00000000..86f6ae76 --- /dev/null +++ b/Scripts/01 timing_windows_config.lua @@ -0,0 +1,59 @@ +local defaultConfig = { + -- put here the added custom windows in the desired order(if you dont they wont rotate in the eval screen) + customWindows = {"dpJ4", "osuManiaOD10"}, + dpJ4 = { + name = "DP Judge 4", + -- if you dont set judgeNames, defaults will be used, see next example for names + judgeWindows = { + marv = 22.5, + perf = 45.0, + great = 90.0, + good = 135.0, + boo = 180.0 + }, + judgeWeights = { + marv = 2, + perf = 2, + great = 1, + good = 0, + boo = -4, + miss = -8, + holdHit = 6, + holdMiss = -6, + mineHit = -8 + } + }, + -- this is a mere example, dont take it too seriously + osuManiaOD10 = { + name = "osu!mania OD10", + judgeNames = { + marv = "300g", + perf = "300", + great = "200", + good = "100", + boo = "50", + miss = "Miss" + }, + judgeWindows = { + marv = 16.0, + perf = 34.0, + great = 67.0, + good = 97.0, + boo = 121.0 + }, + judgeWeights = { + marv = 3, + perf = 3, + great = 2, + good = 1, + boo = 0.5, + miss = 0, + holdHit = 0.5, + holdMiss = -3, + mineHit = 0 + } + } +} + +timingWindowConfig = create_setting("timingWindowConfig", "timingWindowConfig.lua", defaultConfig, -1) +timingWindowConfig:load() diff --git a/Scripts/02 BranchOverrides.lua b/Scripts/02 BranchOverrides.lua index f4063643..2dc3ea9f 100644 --- a/Scripts/02 BranchOverrides.lua +++ b/Scripts/02 BranchOverrides.lua @@ -1,3 +1,18 @@ +function SMOnlineScreen() + if not IsNetSMOnline() then + return "ScreenSelectMusic" + end + for pn in ivalues(GAMESTATE:GetHumanPlayers()) do + if not IsSMOnlineLoggedIn(pn) then + return "ScreenSMOnlineLogin" + end + end + if not IsSMOnlineLoggedIn(pn) then + return "ScreenSMOnlineLogin" + end + return "ScreenNetRoom" +end + Branch.PlayerOptions= function() local pm = GAMESTATE:GetPlayMode() local restricted = { PlayMode_Oni= true, PlayMode_Rave= true, @@ -15,12 +30,11 @@ Branch.PlayerOptions= function() end Branch.AfterSelectProfile = function() - if (THEME:GetMetric("Common","AutoSetStyle") == true) then - -- use SelectStyle in online... - return IsNetConnected() and "ScreenSelectStyle" or "ScreenSelectMusic" - else - return "ScreenSelectMusic" - end + return "ScreenSelectMusic" +end + +Branch.AfterNetSelectProfile = function() + return SMOnlineScreen() end Branch.AfterProfileLoad = function() @@ -29,4 +43,12 @@ end Branch.AfterTitleMenu = function() return Branch.StartGame() +end + +Branch.MultiScreen = function() + if IsNetSMOnline() then + return "ScreenNetSelectProfile" + else + return "ScreenNetworkOptions" + end end \ No newline at end of file diff --git a/Scripts/02 CustomizeGameplay.lua b/Scripts/02 CustomizeGameplay.lua new file mode 100644 index 00000000..cc8a5225 --- /dev/null +++ b/Scripts/02 CustomizeGameplay.lua @@ -0,0 +1,807 @@ +local keymode +local allowedCustomization +local usingReverse +local WIDESCREENWHY = -5 +local WIDESCREENWHX = -5 + +MovableValues = {} + +local function loadValuesTable() + allowedCustomization = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomizeGameplay + usingReverse = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingReverse() + MovableValues.JudgeX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].JudgeX + MovableValues.JudgeY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].JudgeY + MovableValues.JudgeZoom = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].JudgeZoom + MovableValues.ComboX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].ComboX + MovableValues.ComboY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].ComboY + MovableValues.ComboZoom = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].ComboZoom + MovableValues.ErrorBarX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].ErrorBarX + MovableValues.ErrorBarY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].ErrorBarY + MovableValues.ErrorBarWidth = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].ErrorBarWidth + MovableValues.ErrorBarHeight = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].ErrorBarHeight + MovableValues.TargetTrackerX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].TargetTrackerX + MovableValues.TargetTrackerY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].TargetTrackerY + MovableValues.TargetTrackerZoom = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].TargetTrackerZoom + MovableValues.DisplayPercentX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].DisplayPercentX + MovableValues.DisplayPercentY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].DisplayPercentY + MovableValues.DisplayPercentZoom = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].DisplayPercentZoom + MovableValues.NotefieldX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].NotefieldX + MovableValues.NotefieldY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].NotefieldY + MovableValues.NotefieldWidth = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].NotefieldWidth + MovableValues.NotefieldHeight = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].NotefieldHeight + MovableValues.JudgeCounterX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].JudgeCounterX + MovableValues.JudgeCounterY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].JudgeCounterY + MovableValues.NPSGraphX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].NPSGraphX + MovableValues.NPSGraphY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].NPSGraphY + MovableValues.NPSGraphWidth = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].NPSGraphWidth + MovableValues.NPSGraphHeight = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].NPSGraphHeight + MovableValues.NPSDisplayX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].NPSDisplayX + MovableValues.NPSDisplayY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].NPSDisplayY + MovableValues.NPSDisplayZoom = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].NPSDisplayZoom + MovableValues.LeaderboardX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].LeaderboardX + MovableValues.LeaderboardY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].LeaderboardY + MovableValues.LeaderboardSpacing = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].LeaderboardSpacing + MovableValues.LeaderboardWidth = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].LeaderboardWidth + MovableValues.LeaderboardHeight = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].LeaderboardHeight + MovableValues.PlayerInfoP1X = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].PlayerInfoP1X + MovableValues.PlayerInfoP1Y = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].PlayerInfoP1Y + MovableValues.PlayerInfoP1Width = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].PlayerInfoP1Width + MovableValues.PlayerInfoP1Height = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplaySizes[keymode].PlayerInfoP1Height + MovableValues.PracticeCDGraphX = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].PracticeCDGraphX + MovableValues.PracticeCDGraphY = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).GameplayXYCoordinates[keymode].PracticeCDGraphY + + if IsUsingWideScreen() then + MovableValues.TargetTrackerY = MovableValues.TargetTrackerY + WIDESCREENWHY + MovableValues.TargetTrackerX = MovableValues.TargetTrackerX - WIDESCREENWHX + MovableValues.JudgeY = MovableValues.JudgeY - 5 + MovableValues.JudgeX = MovableValues.JudgeX + 5 + end +end + +function setMovableKeymode(key) + keymode = key + loadValuesTable() +end + +local Round = notShit.round +local Floor = notShit.floor +local queuecommand = Actor.queuecommand +local playcommand = Actor.queuecommand +local settext = BitmapText.settext + +local propsFunctions = { + X = Actor.x, + Y = Actor.y, + Zoom = Actor.zoom, + Height = Actor.zoomtoheight, + Width = Actor.zoomtowidth, + AddX = Actor.addx, + AddY = Actor.addy, + Rotation = Actor.rotationz, +} + +Movable = { + message = {}, + current = "None", + pressed = false, + DeviceButton_1 = { + name = "Judge", + textHeader = "Judgment Label Position:", + element = {}, + children = {"Judgment", "Border"}, + properties = {"X", "Y"}, + propertyOffsets = nil, -- manual offsets for stuff hardcoded to be relative to center and maybe other things (init in wifejudgmentspotting) + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -5 + }, + DeviceButton_down = { + property = "Y", + inc = 5 + }, + DeviceButton_left = { + property = "X", + inc = -5 + }, + DeviceButton_right = { + property = "X", + inc = 5 + } + }, + DeviceButton_2 = { -- note: there's almost certainly an update function associated with this that is doing things we aren't aware of + name = "Judge", + textHeader = "Judgment Label Size:", + element = {}, + children = {"Judgment"}, + properties = {"Zoom"}, + elementTree = "GameplaySizes", + noBorder = true, + DeviceButton_up = { + property = "Zoom", + inc = 0.01 + }, + DeviceButton_down = { + property = "Zoom", + inc = -0.01 + } + }, + DeviceButton_3 = { + name = "Combo", + textHeader = "Combo Position:", + element = {}, + children = {"Label", "Number", "Border"}, + properties = {"X", "Y"}, + propertyOffsets = nil, + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -5 + }, + DeviceButton_down = { + property = "Y", + inc = 5 + }, + DeviceButton_left = { + property = "X", + inc = -5 + }, + DeviceButton_right = { + property = "X", + inc = 5 + } + }, + DeviceButton_4 = { -- combo and label are 2 text objects, 1 right aligned and 1 left, this makes border resizing desync from the text sometimes + name = "Combo", -- i really dont want to deal with this right now -mina + textHeader = "Combo Size:", + element = {}, + children = {"Label", "Number"}, + properties = {"Zoom"}, + elementTree = "GameplaySizes", + noBorder = true, + DeviceButton_up = { + property = "Zoom", + inc = 0.01 + }, + DeviceButton_down = { + property = "Zoom", + inc = -0.01 + } + }, + DeviceButton_5 = { + name = "ErrorBar", + textHeader = "Error Bar Position:", + element = {}, -- initialized later + properties = {"X", "Y"}, + children = {"Center", "WeightedBar", "Border"}, + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -5 + }, + DeviceButton_down = { + property = "Y", + inc = 5 + }, + DeviceButton_left = { + property = "X", + inc = -5 + }, + DeviceButton_right = { + property = "X", + inc = 5 + } + }, + DeviceButton_6 = { + name = "ErrorBar", + textHeader = "Error Bar Size:", + element = {}, + properties = {"Width", "Height"}, + children = {"Center", "WeightedBar"}, + elementTree = "GameplaySizes", + DeviceButton_up = { + property = "Height", + inc = 1 + }, + DeviceButton_down = { + property = "Height", + inc = -1 + }, + DeviceButton_left = { + property = "Width", + inc = -10 + }, + DeviceButton_right = { + property = "Width", + inc = 10 + } + }, + DeviceButton_7 = { + name = "TargetTracker", + textHeader = "Goal Tracker Position:", + element = {}, + properties = {"X", "Y"}, + -- no children so the changes are applied to the element itself + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -5 + }, + DeviceButton_down = { + property = "Y", + inc = 5 + }, + DeviceButton_left = { + property = "X", + inc = -5 + }, + DeviceButton_right = { + property = "X", + inc = 5 + } + }, + DeviceButton_8 = { + name = "TargetTracker", + textHeader = "Goal Tracker Size:", + element = {}, + properties = {"Zoom"}, + elementTree = "GameplaySizes", + DeviceButton_up = { + property = "Zoom", + inc = 0.01 + }, + DeviceButton_down = { + property = "Zoom", + inc = -0.01 + } + }, + DeviceButton_w = { + name = "DisplayPercent", + textHeader = "Current Percent Position:", + element = {}, + properties = {"X", "Y"}, + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -5 + }, + DeviceButton_down = { + property = "Y", + inc = 5 + }, + DeviceButton_left = { + property = "X", + inc = -5 + }, + DeviceButton_right = { + property = "X", + inc = 5 + } + }, + DeviceButton_e = { + name = "DisplayPercent", + textHeader = "Current Percent Size:", + element = {}, + properties = {"Zoom"}, + elementTree = "GameplaySizes", + DeviceButton_up = { + property = "Zoom", + inc = 0.01 + }, + DeviceButton_down = { + property = "Zoom", + inc = -0.01 + } + }, + DeviceButton_r = { + name = "Notefield", + textHeader = "Notefield Position:", + element = {}, + properties = {"X", "Y"}, + elementTree = "GameplayXYCoordinates", + noBorder = true, + DeviceButton_up = { + notefieldY = true, + property = "AddY", + inc = -3 + }, + DeviceButton_down = { + notefieldY = true, + property = "AddY", + inc = 3 + }, + DeviceButton_left = { + property = "AddX", + inc = -3 + }, + DeviceButton_right = { + property = "AddX", + inc = 3 + } + }, + DeviceButton_t = { + name = "Notefield", + textHeader = "Notefield Size:", + element = {}, + elementList = true, -- god bless the notefield + properties = {"Width", "Height"}, + elementTree = "GameplaySizes", + noBorder = true, + DeviceButton_up = { + property = "Height", + inc = 0.01 + }, + DeviceButton_down = { + property = "Height", + inc = -0.01 + }, + DeviceButton_left = { + property = "Width", + inc = -0.01 + }, + DeviceButton_right = { + property = "Width", + inc = 0.01 + } + }, + DeviceButton_y = { + name = "NPSDisplay", + textHeader = "NPS Display Position:", + element = {}, + properties = {"X", "Y"}, + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -5 + }, + DeviceButton_down = { + property = "Y", + inc = 5 + }, + DeviceButton_left = { + property = "X", + inc = -5 + }, + DeviceButton_right = { + property = "X", + inc = 5 + } + }, + DeviceButton_u = { + name = "NPSDisplay", + textHeader = "NPS Display Size:", + element = {}, + properties = {"Zoom"}, + elementTree = "GameplaySizes", + DeviceButton_up = { + property = "Zoom", + inc = 0.01 + }, + DeviceButton_down = { + property = "Zoom", + inc = -0.01 + } + }, + DeviceButton_i = { + name = "NPSGraph", + textHeader = "NPS Graph Position:", + element = {}, + properties = {"X", "Y"}, + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -5 + }, + DeviceButton_down = { + property = "Y", + inc = 5 + }, + DeviceButton_left = { + property = "X", + inc = -5 + }, + DeviceButton_right = { + property = "X", + inc = 5 + } + }, + DeviceButton_o = { + name = "NPSGraph", + textHeader = "NPS Graph Size:", + element = {}, + properties = {"Width", "Height"}, + noBorder = true, + elementTree = "GameplaySizes", + DeviceButton_up = { + property = "Height", + inc = 0.01 + }, + DeviceButton_down = { + property = "Height", + inc = -0.01 + }, + DeviceButton_left = { + property = "Width", + inc = -0.01 + }, + DeviceButton_right = { + property = "Width", + inc = 0.01 + } + }, + DeviceButton_p = { + name = "JudgeCounter", + textHeader = "Judge Counter Position:", + element = {}, + properties = {"X", "Y"}, + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -3 + }, + DeviceButton_down = { + property = "Y", + inc = 3 + }, + DeviceButton_left = { + property = "X", + inc = -3 + }, + DeviceButton_right = { + property = "X", + inc = 3 + } + }, + DeviceButton_a = { + name = "Leaderboard", + textHeader = "Leaderboard Position:", + properties = {"X", "Y"}, + element = {}, + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -3 + }, + DeviceButton_down = { + property = "Y", + inc = 3 + }, + DeviceButton_left = { + property = "X", + inc = -3 + }, + DeviceButton_right = { + property = "X", + inc = 3 + } + }, + DeviceButton_s = { + name = "Leaderboard", + textHeader = "Leaderboard Size:", + properties = {"Width", "Height"}, + element = {}, + elementTree = "GameplaySizes", + noBorder = true, + DeviceButton_up = { + property = "Height", + inc = 0.01 + }, + DeviceButton_down = { + property = "Height", + inc = -0.01 + }, + DeviceButton_left = { + property = "Width", + inc = -0.01 + }, + DeviceButton_right = { + property = "Width", + inc = 0.01 + } + }, + DeviceButton_d = { + name = "Leaderboard", + textHeader = "Leaderboard Spacing:", + properties = {"Spacing"}, + elementTree = "GameplaySizes", + DeviceButton_up = { + arbitraryInc = true, + property = "Spacing", + inc = -0.3 + }, + DeviceButton_down = { + arbitraryInc = true, + property = "Spacing", + inc = 0.3 + }, + }, + DeviceButton_j = { + name = "PlayerInfoP1", + textHeader = "PlayerInfo Position:", + element = {}, + noBorder = true, + properties = {"X", "Y"}, + -- propertyOffsets = {"178", "10"}, + elementTree = "GameplayXYCoordinates", + DeviceButton_up = { + property = "Y", + inc = -3 + }, + DeviceButton_down = { + property = "Y", + inc = 3 + }, + DeviceButton_left = { + property = "X", + inc = -3 + }, + DeviceButton_right = { + property = "X", + inc = 3 + } + }, + DeviceButton_k = { + name = "PlayerInfoP1", + textHeader = "PlayerInfo Size:", + properties = {"Width", "Height"}, + element = {}, + noBorder = true, + elementTree = "GameplaySizes", + DeviceButton_up = { + property = "Height", + inc = 0.01 + }, + DeviceButton_down = { + property = "Height", + inc = -0.01 + }, + DeviceButton_left = { + property = "Width", + inc = -0.01 + }, + DeviceButton_right = { + property = "Width", + inc = 0.01 + } + }, + DeviceButton_z = { + name = "PracticeCDGraph", + textHeader = "Chord Density Graph Position:", + properties = {"X","Y"}, + element = {}, + elementTree = "GameplayXYCoordinates", + propertyOffsets = nil, + DeviceButton_up = { + property = "Y", + inc = -3 + }, + DeviceButton_down = { + property = "Y", + inc = 3 + }, + DeviceButton_left = { + property = "X", + inc = -3 + }, + DeviceButton_right = { + property = "X", + inc = 3 + } + } +} + +local function updatetext(button) + local text = {Movable[button].textHeader} + for _, prop in ipairs(Movable[button].properties) do + local fullProp = Movable[button].name .. prop + text[#text + 1] = prop .. ": " .. MovableValues[fullProp] + end + Movable.message:settext(table.concat(text, "\n")) + Movable.message:visible(Movable.pressed) +end + +function MovableInput(event) + if getAutoplay() ~= 0 then + -- this will eat any other mouse input than a right click (toggle) + -- so we don't have to worry about anything weird happening with the ersatz inputs -mina + if event.DeviceInput.is_mouse then + if event.DeviceInput.button == "DeviceButton_right mouse button" then + Movable.current = "None" + Movable.pressed = false + Movable.message:visible(Movable.pressed) + end + return + end + + local button = event.DeviceInput.button + event.hellothisismouse = event.hellothisismouse and true or false -- so that's why bools kept getting set to nil -mina + local notReleased = not (event.type == "InputEventType_Release") + -- changed to toggle rather than hold down -mina + if (Movable[button] and Movable[button].condition and notReleased) or event.hellothisismouse then + Movable.pressed = not Movable.pressed or event.hellothisismouse -- this stuff is getting pretty hacky now -mina + if Movable.current ~= event.DeviceInput.button and not event.hellothisismouse then + Movable.pressed = true -- allow toggling using the kb to directly move to a different key rather than forcing an untoggle first -mina + end + Movable.current = button + if not Movable.pressed then + Movable.current = "None" + end + updatetext(button) -- this will only update the text when the toggles occur + end + + local current = Movable[Movable.current] + + -- left/right move along the x axis and up/down along the y; set them directly here -mina + if event.hellothisismouse then + if event.axis == "x" then + button = "DeviceButton_left" + else + button = "DeviceButton_up" + end + Movable.pressed = true -- we need to do this or the mouse input facsimile will toggle on when moving x, and off when moving y + end + + if Movable.pressed and current[button] and current.condition and notReleased and current.external == nil then + local curKey = current[button] + local keyProperty = curKey.property + local prop = current.name .. string.gsub(keyProperty, "Add", "") + local newVal + + -- directly set newval if we're using the mouse -mina + if event.hellothisismouse then + newVal = event.val + else + newVal = MovableValues[prop] + (curKey.inc * ((curKey.notefieldY and not usingReverse) and -1 or 1)) + end + + MovableValues[prop] = newVal + if curKey.arbitraryFunction then + if curKey.arbitraryInc then + curKey.arbitraryFunction(curKey.inc) + else + curKey.arbitraryFunction(newVal) + end + elseif current.children then + for _, attribute in ipairs(current.children) do + propsFunctions[curKey.property](current.element[attribute], newVal) + end + elseif current.elementList then + for _, elem in ipairs(current.element) do + propsFunctions[keyProperty](elem, newVal) + end + elseif keyProperty == "AddX" or keyProperty == "AddY" then + propsFunctions[keyProperty](current.element, curKey.inc) + else + propsFunctions[keyProperty](current.element, newVal) + end + + if not current.noBorder then + local border = Movable[Movable.current]["Border"] + if keyProperty == "Height" or keyProperty == "Width" or keyProperty == "Zoom" then + border:playcommand("Change" .. keyProperty, {val = newVal} ) + end + end + + if not event.hellothisismouse then + updatetext(Movable.current) -- updates text when keyboard movements are made (mouse already updated) + end + playerConfig:get_data(pn_to_profile_slot(PLAYER_1))[current.elementTree][keymode][prop] = newVal + playerConfig:set_dirty(pn_to_profile_slot(PLAYER_1)) + playerConfig:save(pn_to_profile_slot(PLAYER_1)) + end + end + return false +end + +function setBorderAlignment(self, h, v) + self:RunCommandsOnChildren( + function(self) + self:halign(h):valign(v) + end + ) + self:GetChild("hideybox"):addx(-2 * (h - 0.5)) + self:GetChild("hideybox"):addy(-2 * (v - 0.5)) +end + +function setBorderToText(b, t) + b:playcommand("ChangeWidth", {val = t:GetZoomedWidth()}) + b:playcommand("ChangeHeight", {val = t:GetZoomedHeight()}) + b:playcommand("ChangeZoom", {val = t:GetParent():GetZoom()}) +end + +-- this is supreme lazy -mina +local function elementtobutton(name) + name = name == "Judgment" and "Judge" or name + for k,v in pairs(Movable) do + if type(v) == 'table' and v.name == name and v.properties[1] == "X" then + return k + end + end +end + +local function bordermousereact(self) + self:queuecommand("mousereact") +end + +local function movewhendragged(self) + -- this is a somewhat dangerous hierarchical assumption but it should help us get organied in the short term -mina + local b = elementtobutton(self:GetParent():GetParent():GetName()) + if isOver(self) or (Movable.pressed and Movable.current == b) then + if Movable.pressed and Movable.current == b then + self:GetParent():diffusealpha(0.75) -- this is active + else + self:GetParent():diffusealpha(0.35) -- this has been moused over + end + + -- second half of the expr stops elements from being activated if you mouse over them while moving something else + if INPUTFILTER:IsBeingPressed("Mouse 0", "Mouse") and (Movable.current == b or Movable.current == "None") then + local nx = Round(INPUTFILTER:GetMouseX()) + local ny = Round(INPUTFILTER:GetMouseY()) + if Movable[b].propertyOffsets ~= nil then + nx = nx - Movable[b].propertyOffsets[1] + ny = ny - Movable[b].propertyOffsets[2] + end + MovableInput({DeviceInput = {button = b}, hellothisismouse = true, axis = "x", val = nx}) + MovableInput({DeviceInput = {button = b}, hellothisismouse = true, axis = "y", val = ny}) + end + elseif Movable.pressed then + self:GetParent():diffusealpha(0.35) -- something is active, but not this + else + self:GetParent():diffusealpha(0.1) -- nothing is active and this is not moused over + end +end + +-- border function in use -mina +function MovableBorder(width, height, bw, x, y) + if not allowedCustomization then return end -- we don't want to be loading all this garbage if we aren't in customization + return Def.ActorFrame { + Name = "Border", + InitCommand=function(self) + self:xy(x,y):diffusealpha(0) + self:SetUpdateFunction(bordermousereact) + end, + ChangeWidthCommand=function(self, params) + self:GetChild("xbar"):zoomx(params.val) + self:GetChild("showybox"):zoomx(params.val) + self:GetChild("hideybox"):zoomx(params.val-2*bw) + end, + ChangeHeightCommand=function(self, params) + self:GetChild("ybar"):zoomy(params.val) + self:GetChild("showybox"):zoomy(params.val) + self:GetChild("hideybox"):zoomy(params.val-2*bw) + end, + ChangeZoomCommand=function(self,params) + local wot = self:GetZoom()/(1/params.val) + self:zoom(1/params.val) + self:playcommand("ChangeWidth", {val = self:GetChild("showybox"):GetZoomX() * wot}) + self:playcommand("ChangeHeight", {val = self:GetChild("showybox"):GetZoomY() * wot}) + end, + Def.Quad { + Name = "xbar", + InitCommand=function(self) + self:zoomto(width,bw):diffusealpha(0.5) -- did not realize this was multiplicative with parent's value -mina + end + }, + Def.Quad { + Name = "ybar", + InitCommand=function(self) + self:zoomto(bw,height):diffusealpha(0.5) + end + }, + Def.Quad { + Name = "hideybox", + InitCommand=function(self) + self:zoomto(width-2*bw, height-2*bw):MaskSource(true) + end + }, + Def.Quad { + Name = "showybox", + InitCommand=function(self) + self:zoomto(width,height):MaskDest() + end, + mousereactCommand=function(self) + movewhendragged(self) -- this quad owns the mouse movement function -mina + end + }, + } +end diff --git a/Scripts/02 GhettoGameState.lua b/Scripts/02 GhettoGameState.lua index 04c15d35..a574825b 100644 --- a/Scripts/02 GhettoGameState.lua +++ b/Scripts/02 GhettoGameState.lua @@ -2,9 +2,181 @@ GHETTOGAMESTATE = { lastSelectedFolder = "", - lastPlayedSecond = 0 + lastPlayedSecond = 0, + musicwheel = nil, + musicsearch = "", + onlineStatus = "Local", + SSM = nil, + filterTags = {}, + tagFilterMode = false, -- false means OR + goalsByChartKey = {}, + replayScore = nil, + replayIsOnline = nil, + replayList = {}, + replayScoreID = nil, + lastOnlineRank = nil } +function GHETTOGAMESTATE.checkOnlineRank(self) + if DLMAN:IsLoggedIn() then + if self.lastOnlineRank ~= nil then + return self.lastOnlineRank - DLMAN:GetSkillsetRank("Overall") + else + self.lastOnlineRank = DLMAN:GetSkillsetRank("Overall") + end + end + return 0 +end + +local function continueReplayCheck(leaderboard) + local score = nil + for _,g in ipairs(leaderboard) do + if g:GetScoreid() == GHETTOGAMESTATE.replayScoreID then + score = g + break + end + end + if score ~= nil then + DLMAN:RequestOnlineScoreReplayData( + score, + function() + MESSAGEMAN:Broadcast("GhettoReplayStart", {score = score}) + end + ) + end + GHETTOGAMESTATE.replayIsOnline = nil + GHETTOGAMESTATE.replayScore = nil + GHETTOGAMESTATE.replayChartkey = nil +end + +function GHETTOGAMESTATE.checkForReplayToPlay(self) + if self.replayScore ~= nil and self.SSM ~= nil then + if self.replayIsOnline then + DLMAN:RequestChartLeaderBoardFromOnline( + self.replayChartkey, + function(leaderboard) + continueReplayCheck(leaderboard) + end + ) + return + else + self.SSM:PlayReplay(self.replayScore) + self.replayScore = nil + self.replayIsOnline = nil + self.replayChartkey = nil + self.replayScoreID = nil + end + end +end + +function GHETTOGAMESTATE.setReplay(self, score, online) + self.replayChartkey = score:GetChartKey() + self.replayScoreID = score:GetScoreid() + self.replayScore = score + self.replayIsOnline = online +end + +function GHETTOGAMESTATE.resetGoalTable(self) + self.goalsByChartKey = {} + for k,v in ipairs(PROFILEMAN:GetProfile(PLAYER_1):GetGoalTable()) do + local key = v:GetChartKey() + local goals = self.goalsByChartKey[key] + if not goals then + goals = {} + self.goalsByChartKey[key] = goals + end + goals[#goals + 1] = v + end +end + +function GHETTOGAMESTATE.getGoalsByChartKey(self) + return self.goalsByChartKey +end + +function GHETTOGAMESTATE.getLowestGoalTypeBySong(self, song) + -- outputs 0, 1, 2 + -- these are based on song, not just chart key + -- the entire chart and its associated diffs are checked because they are fit into a single musicwheel item + -- 0 = no goals + -- 1 = at least 1 unfinished goal + -- 2 = has goals and all are finished + local steps = song:GetAllSteps() + local output = 0 + for i = 1, #steps do + local key = steps[i]:GetChartKey() + local goals = self.goalsByChartKey[key] + if goals == nil then + return 0 + end + for k,v in ipairs(goals) do + if not v:IsAchieved() and not v:IsVacuous() then + return 1 + else + output = 2 + end + end + end + return output +end + +-- very bad cheaty way to get the music wheel across overlay screens +function GHETTOGAMESTATE.setMusicWheel(self, screen) + self.musicwheel = screen:GetMusicWheel() +end + +function GHETTOGAMESTATE.getMusicWheel(self) + return self.musicwheel +end + +function GHETTOGAMESTATE.setSSM(self, screen) + self.SSM = screen +end + +function GHETTOGAMESTATE.getSSM(self) + return self.SSM +end + +function GHETTOGAMESTATE.setFilterTags(self, given) + self.filterTags = given +end + +function GHETTOGAMESTATE.getFilterTags(self) + return self.filterTags +end + +function GHETTOGAMESTATE.setTagFilterMode(self, given) + self.tagFilterMode = given +end + +function GHETTOGAMESTATE.getTagFilterMode(self) + return self.tagFilterMode +end + + +function GHETTOGAMESTATE.setOnlineStatus(self, given) + if given ~= nil then + self.onlineStatus = given + return + end + if self.onlineStatus == "Invalid" or self.onlineStatus == "Online" then + self.onlineStatus = "Local" + else + self.onlineStatus = "Online" + end +end + +function GHETTOGAMESTATE.getOnlineStatus(self) + return self.onlineStatus +end + +-- store and retrieve the music filter strings when closing and reopening the overlay +function GHETTOGAMESTATE.setMusicSearch(self, given) + self.musicsearch = given +end +function GHETTOGAMESTATE.getMusicSearch(self) + return self.musicsearch +end + --returns current autoplay type. returns a integer between 0~2 corresponding to --human, autoplay and autoplay cpu respectively. function GHETTOGAMESTATE.getAutoplay() diff --git a/Scripts/02 TextBanner.lua b/Scripts/02 TextBanner.lua index 84f14965..03eefdf5 100644 --- a/Scripts/02 TextBanner.lua +++ b/Scripts/02 TextBanner.lua @@ -1,10 +1,10 @@ -local mainMaxWidth = capWideScale(get43size(280),280); -- zoom w/subtitle is 0.75 (multiply by 1.25) -local subMaxWidth = capWideScale(get43size(280),280); -- zoom is 0.6 (multiply zoom,1 value by 1.4) -local artistMaxWidth = capWideScale(get43size(280),280); +local mainMaxWidth = capWideScale(get43size(280),280) -- zoom w/subtitle is 0.75 (multiply by 1.25) +local subMaxWidth = capWideScale(get43size(280),280) -- zoom is 0.6 (multiply zoom,1 value by 1.4) +local artistMaxWidth = capWideScale(get43size(280),280) -local mainMaxWidthHighScore = 192; -- zoom w/subtitle is 0.75 (multiply by 1.25) -local subMaxWidthHighScore = 280; -- zoom is 0.6 (multiply zoom,1 value by 1.4) -local artistMaxWidthHighScore = 280/0.8; +local mainMaxWidthHighScore = 192 -- zoom w/subtitle is 0.75 (multiply by 1.25) +local subMaxWidthHighScore = 280 -- zoom is 0.6 (multiply zoom,1 value by 1.4) +local artistMaxWidthHighScore = 280/0.8 --[[ -- The old (cmd(blah))(Actor) syntax is hard to read. diff --git a/Scripts/02 ThemePrefs.lua b/Scripts/02 ThemePrefs.lua index 71c8fb2e..3ed789bb 100644 --- a/Scripts/02 ThemePrefs.lua +++ b/Scripts/02 ThemePrefs.lua @@ -41,123 +41,94 @@ end function JudgeType() local t = { - Name = "JudgeType"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = { THEME:GetString('OptionNames','Off'),'No Highlights','On'}; + Name = "JudgeType", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = { THEME:GetString('OptionNames','Off'),'No Highlights','On'}, LoadSelections = function(self, list, pn) local prefs = playerConfig:get_data(pn_to_profile_slot(pn)).JudgeType list[prefs+1] = true - end; + end, SaveSelections = function(self, list, pn) local value if list[3] then - value = 2; + value = 2 elseif list[2] then - value = 1; + value = 1 else - value = 0; - end; + value = 0 + end playerConfig:get_data(pn_to_profile_slot(pn)).JudgeType = value playerConfig:set_dirty(pn_to_profile_slot(pn)) playerConfig:save(pn_to_profile_slot(pn)) - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end - function AvgScoreType() + function TargetTracker() local t = { - Name = "AvgScoreType"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = {THEME:GetString('OptionNames','Off'),'DP','%Score','MIGS' }; + Name = "TargetTracker", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = {THEME:GetString("OptionNames", "Off"), THEME:GetString("OptionNames", "On")}, LoadSelections = function(self, list, pn) - local prefs = playerConfig:get_data(pn_to_profile_slot(pn)).AvgScoreType - list[prefs+1] = true - end; - SaveSelections = function(self, list, pn) - local value - if list[4] then - value = 3; - elseif list[3] then - value = 2; - elseif list[2] then - value = 1; + local pref = playerConfig:get_data(pn_to_profile_slot(pn)).TargetTracker + if pref then + list[2] = true else - value = 0; - end; - playerConfig:get_data(pn_to_profile_slot(pn)).AvgScoreType = value - playerConfig:set_dirty(pn_to_profile_slot(pn)) - playerConfig:save(pn_to_profile_slot(pn)) - end; - }; - setmetatable( t, t ); - return t; - end; - - function GhostScoreType() - local t = { - Name = "GhostScoreType"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = { THEME:GetString('OptionNames','Off'),'DP','%Score','MIGS' }; - LoadSelections = function(self, list, pn) - local prefs = playerConfig:get_data(pn_to_profile_slot(pn)).GhostScoreType - list[prefs+1] = true - end; + list[1] = true + end + end, SaveSelections = function(self, list, pn) local value - if list[4] then - value = 3; - elseif list[3] then - value = 2; - elseif list[2] then - value = 1; - else - value = 0; - end; - playerConfig:get_data(pn_to_profile_slot(pn)).GhostScoreType = value + value = list[2] + playerConfig:get_data(pn_to_profile_slot(pn)).TargetTracker = value playerConfig:set_dirty(pn_to_profile_slot(pn)) playerConfig:save(pn_to_profile_slot(pn)) - end; - }; - setmetatable( t, t ); - return t; - end; - + end + } + setmetatable(t, t) + return t + end - local tChoices = {}; - for i=0,100 do - tChoices[#tChoices+1] = tostring(i)..'%'; - end; - function GhostTarget() + local tChoices = {} + for i = 1, 99 do + tChoices[i] = tostring(i) .. "%" + end + for i = 1, 3 do + tChoices[99 + i] = tostring(99 + i * 0.25) .. "%" + end + for i = 1, 4 do + tChoices[#tChoices + 1] = tostring(99.96 + i * 0.01) .. "%" + end + function TargetGoal() local t = { - Name = "GhostTarget"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = tChoices; + Name = "TargetGoal", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = tChoices, LoadSelections = function(self, list, pn) - local prefs = playerConfig:get_data(pn_to_profile_slot(pn)).GhostTarget+1 - list[prefs] = true; - end; + local prefsval = playerConfig:get_data(pn_to_profile_slot(pn)).TargetGoal + local index = IndexOf(tChoices, prefsval .. "%") + list[index] = true + end, SaveSelections = function(self, list, pn) local found = false - for i=1,#list do + for i = 1, #list do if not found then if list[i] == true then - local value = i-1; - playerConfig:get_data(pn_to_profile_slot(pn)).GhostTarget = value + local value = i + playerConfig:get_data(pn_to_profile_slot(pn)).TargetGoal = + tonumber(string.sub(tChoices[value], 1, #tChoices[value] - 1)) found = true end end @@ -166,78 +137,108 @@ end playerConfig:save(pn_to_profile_slot(pn)) end } - setmetatable( t, t ) + setmetatable(t, t) + return t + end + + function TargetTrackerMode() + local t = { + Name = "TargetTrackerMode", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = {THEME:GetString("OptionNames", "SetPercent"), THEME:GetString("OptionNames", "PersonalBest")}, + LoadSelections = function(self, list, pn) + local pref = playerConfig:get_data(pn_to_profile_slot(pn)).TargetTrackerMode + list[pref + 1] = true + end, + SaveSelections = function(self, list, pn) + local value + if list[2] then + value = 1 + else + value = 0 + end + playerConfig:get_data(pn_to_profile_slot(pn)).TargetTrackerMode = value + playerConfig:set_dirty(pn_to_profile_slot(pn)) + playerConfig:save(pn_to_profile_slot(pn)) + end + } + setmetatable(t, t) return t end function ErrorBar() local t = { - Name = "ErrorBar"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = { THEME:GetString('OptionNames','Off'),'On'}; + Name = "ErrorBar", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = {THEME:GetString("OptionNames", "Off"), THEME:GetString("OptionNames", "On"), THEME:GetString("OptionNames", "EWMA")}, LoadSelections = function(self, list, pn) local pref = playerConfig:get_data(pn_to_profile_slot(pn)).ErrorBar - if pref then - list[2] = true; - else - list[1] = true; - end; - end; + list[pref + 1] = true + end, SaveSelections = function(self, list, pn) local value - value = list[2] + if list[1] == true then + value = 0 + elseif list[2] == true then + value = 1 + else + value = 2 + end playerConfig:get_data(pn_to_profile_slot(pn)).ErrorBar = value playerConfig:set_dirty(pn_to_profile_slot(pn)) playerConfig:save(pn_to_profile_slot(pn)) - end; - }; - setmetatable( t, t ); - return t; - end + end + } + setmetatable(t, t) + return t + end function PaceMaker() local t = { - Name = "PaceMaker"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = { THEME:GetString('OptionNames','Off'),'On'}; + Name = "PaceMaker", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = { THEME:GetString('OptionNames','Off'),'On'}, LoadSelections = function(self, list, pn) local pref = playerConfig:get_data(pn_to_profile_slot(pn)).PaceMaker if pref then - list[2] = true; + list[2] = true else - list[1] = true; - end; - end; + list[1] = true + end + end, SaveSelections = function(self, list, pn) local value value = list[2] playerConfig:get_data(pn_to_profile_slot(pn)).PaceMaker = value playerConfig:set_dirty(pn_to_profile_slot(pn)) playerConfig:save(pn_to_profile_slot(pn)) - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function LaneCover() local t = { - Name = "LaneCover"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = { THEME:GetString('OptionNames','Off'),'Sudden','Hidden'}; + Name = "LaneCover", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = { THEME:GetString('OptionNames','Off'),'Sudden','Hidden'}, LoadSelections = function(self, list, pn) local pref = playerConfig:get_data(pn_to_profile_slot(pn)).LaneCover - list[pref+1] = true; - end; + list[pref+1] = true + end, SaveSelections = function(self, list, pn) local value if list[1] == true then @@ -246,24 +247,24 @@ end value = 1 else value = 2 - end; + end playerConfig:get_data(pn_to_profile_slot(pn)).LaneCover = value playerConfig:set_dirty(pn_to_profile_slot(pn)) playerConfig:save(pn_to_profile_slot(pn)) - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function NPSDisplay() local t = { - Name = "NPSDisplay"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectMultiple"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = {"NPS Display","NPS Graph"}; + Name = "NPSDisplay", + LayoutType = "ShowAllInRow", + SelectType = "SelectMultiple", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = {"NPS Display","NPS Graph"}, LoadSelections = function(self, list, pn) local npsDisplay = playerConfig:get_data(pn_to_profile_slot(pn)).NPSDisplay local npsGraph = playerConfig:get_data(pn_to_profile_slot(pn)).NPSGraph @@ -273,106 +274,85 @@ end if npsGraph then list[2] = true end - end; + end, SaveSelections = function(self, list, pn) playerConfig:get_data(pn_to_profile_slot(pn)).NPSDisplay = list[1] playerConfig:get_data(pn_to_profile_slot(pn)).NPSGraph = list[2] playerConfig:set_dirty(pn_to_profile_slot(pn)) playerConfig:save(pn_to_profile_slot(pn)) - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function CBHighlight() local t = { - Name = "CBHighlight"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = { THEME:GetString('OptionNames','Off'),'On'}; + Name = "CBHighlight", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = { THEME:GetString('OptionNames','Off'),'On'}, LoadSelections = function(self, list, pn) local pref = playerConfig:get_data(pn_to_profile_slot(pn)).CBHighlight if pref then - list[2] = true; + list[2] = true else - list[1] = true; - end; - end; + list[1] = true + end + end, SaveSelections = function(self, list, pn) local value value = list[2] playerConfig:get_data(pn_to_profile_slot(pn)).CBHighlight = value playerConfig:set_dirty(pn_to_profile_slot(pn)) playerConfig:save(pn_to_profile_slot(pn)) - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end - - --unused - --[[ - function Avatars() - local directory = FILEMAN:GetDirListing("Themes/"..THEME:GetCurThemeName().."/Graphics/Player avatar/") + + function LeaderBoard() local t = { - Name = "Avatars"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = false; - ExportOnChange = true; - Choices = directory; + Name = "Leaderboard", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = {THEME:GetString("OptionNames", "Off"), THEME:GetString("OptionNames", "On")}, LoadSelections = function(self, list, pn) - local profile = PROFILEMAN:GetProfile(pn) - local GUID = profile:GetGUID() - local pref = themeConfig:get_data().avatar[GUID] - local found = false - for i=1,#list do - if pref == directory[i] then - list[i] = true - found = true - end; - end; - if not found then + local pref = playerConfig:get_data(pn_to_profile_slot(pn)).leaderboardEnabled + if pref then + list[2] = true + else list[1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) - local profile = PROFILEMAN:GetProfile(pn) - local GUID = profile:GetGUID() local value - local found = false - for i=1,#list do - if not found then - if list[i] == true then - local value = directory[i]; - themeConfig:get_data().avatar[GUID] = value - found = true - end - end - end - themeConfig:set_dirty() - themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; - end - --]] + value = list[2] + playerConfig:get_data(pn_to_profile_slot(pn)).leaderboardEnabled = value + playerConfig:set_dirty(pn_to_profile_slot(pn)) + playerConfig:save(pn_to_profile_slot(pn)) + end + } + setmetatable(t, t) + return t + end --=============================================== --Globals function DefaultScoreType() local t = { - Name = "DefaultScoreType"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "DP","PS","MIGS"}; + Name = "DefaultScoreType", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "DP","PS","MIGS"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.DefaultScoreType if pref == 1 then @@ -381,8 +361,8 @@ function DefaultScoreType() list[2] = true else list[3] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] == true then @@ -391,24 +371,24 @@ function DefaultScoreType() value = 2 else value = 3 - end; + end themeConfig:get_data().global.DefaultScoreType = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function TipType() local t = { - Name = "TipType"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","Tips","Random Phrases"}; + Name = "TipType", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","Tips","Random Phrases"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.TipType if pref == 1 then @@ -417,8 +397,8 @@ function TipType() list[2] = true else list[3] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] == true then @@ -427,88 +407,120 @@ function TipType() value = 2 else value = 3 - end; + end themeConfig:get_data().global.TipType = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t +end + +function PlayerInfoType() + local t = { + Name = "PlayerInfoType", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Minimal","Full"}, + LoadSelections = function(self, list, pn) + local pref = themeConfig:get_data().global.PlayerInfoType + if pref then + list[2] = true + else + list[1] = true + end + end, + SaveSelections = function(self, list, pn) + local value + if list[1] then + value = false + else + value = true + end + themeConfig:get_data().global.PlayerInfoType = value + themeConfig:set_dirty() + themeConfig:save() + end + } + setmetatable( t, t ) + return t end function SongBGEnabled() local t = { - Name = "SongBGEnabled"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","On"}; + Name = "SongBGEnabled", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.SongBGEnabled if pref then list[2] = true else list[1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] then value = false else value = true - end; + end themeConfig:get_data().global.SongBGEnabled = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function SongBGMouseEnabled() local t = { - Name = "SongBGMouseEnabled"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","On"}; + Name = "SongBGMouseEnabled", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.SongBGMouseEnabled if pref then list[2] = true else list[1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] then value = false else value = true - end; + end themeConfig:get_data().global.SongBGMouseEnabled = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function EvalBGType() local t = { - Name = "EvalBGType"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Song Background","Clear+Grade Background","Grade Background only"}; + Name = "EvalBGType", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Song Background","Clear+Grade Background","Grade Background only"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().eval.SongBGType if pref == 1 then @@ -517,8 +529,8 @@ function EvalBGType() list[2] = true else list[3] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] == true then @@ -527,160 +539,193 @@ function EvalBGType() value = 2 else value = 3 - end; + end themeConfig:get_data().eval.SongBGType = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; -end + end + } + setmetatable( t, t ) + return t +end function Particles() local t = { - Name = "Particles"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","On"}; + Name = "Particles", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.Particles if pref then list[2] = true else list[1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] then value = false else value = true - end; + end themeConfig:get_data().global.Particles = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function RateSort() local t = { - Name = "RateSort"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","On"}; + Name = "RateSort", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.RateSort if pref then list[2] = true else list[1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] then value = false else value = true - end; + end themeConfig:get_data().global.RateSort = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function HelpMenu() local t = { - Name = "HelpMenu"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","On"}; + Name = "HelpMenu", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.HelpMenu if pref then list[2] = true else list[1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] then value = false else value = true - end; + end themeConfig:get_data().global.HelpMenu = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function MeasureLines() local t = { - Name = "MeasureLines"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","On"}; + Name = "MeasureLines", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.MeasureLines if pref then list[2] = true else list[1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] then value = false else value = true - end; + end themeConfig:get_data().global.MeasureLines = value themeConfig:set_dirty() themeConfig:save() THEME:ReloadMetrics() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t +end + +function EvalScoreboard() + local t = { + Name = "EvalScoreboard", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Old","New"}, + LoadSelections = function(self, list, pn) + local pref = themeConfig:get_data().global.EvalScoreboard + if pref then + list[2] = true + else + list[1] = true + end + end, + SaveSelections = function(self, list, pn) + local value + if list[1] then + value = false + else + value = true + end + themeConfig:get_data().global.EvalScoreboard = value + themeConfig:set_dirty() + themeConfig:save() + THEME:ReloadMetrics() + end + } + setmetatable( t, t ) + return t end function ProgressBar() local t = { - Name = "ProgressBar"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","Bottom", "Top",}; + Name = "ProgressBar", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","Bottom", "Top",}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.ProgressBar if pref then list[pref+1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] == true then @@ -688,141 +733,419 @@ function ProgressBar() elseif list[2] == true then value = 1 else - value = 2; - end; - themeConfig:get_data().global.ProgressBar = value; - themeConfig:set_dirty(); - themeConfig:save(); - end; - }; - setmetatable( t, t ); - return t; + value = 2 + end + themeConfig:get_data().global.ProgressBar = value + themeConfig:set_dirty() + themeConfig:save() + end + } + setmetatable( t, t ) + return t +end + +function CustomizeGameplay() + local t = { + Name = "CustomizeGameplay", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = {THEME:GetString("OptionNames", "Off"), THEME:GetString("OptionNames", "On")}, + LoadSelections = function(self, list, pn) + local pref = playerConfig:get_data(pn_to_profile_slot(pn)).CustomizeGameplay + if pref then + list[2] = true + else + list[1] = true + end + end, + SaveSelections = function(self, list, pn) + playerConfig:get_data(pn_to_profile_slot(pn)).CustomizeGameplay = list[2] + playerConfig:set_dirty(pn_to_profile_slot(pn)) + playerConfig:save(pn_to_profile_slot(pn)) + end + } + setmetatable(t, t) + return t end +local RSChoices = {} +for i = 1, 250 do + RSChoices[i] = tostring(i) .. "%" +end +function ReceptorSize() + local t = { + Name = "ReceptorSize", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = RSChoices, + LoadSelections = function(self, list, pn) + local prefs = playerConfig:get_data(pn_to_profile_slot(pn)).ReceptorSize + list[prefs] = true + end, + SaveSelections = function(self, list, pn) + local found = false + for i = 1, #list do + if not found then + if list[i] == true then + local value = i + playerConfig:get_data(pn_to_profile_slot(pn)).ReceptorSize = value + found = true + end + end + end + playerConfig:set_dirty(pn_to_profile_slot(pn)) + playerConfig:save(pn_to_profile_slot(pn)) + end + } + setmetatable(t, t) + return t +end + +local LBChoices = {} +for i = 1, 15 do + LBChoices[i] = tostring(i) +end +function LeaderboardSlots() + local t = { + Name = "LeaderboardSlots", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = LBChoices, + LoadSelections = function(self, list, pn) + local prefs = themeConfig:get_data().global.LeaderboardSlots + list[prefs] = true + end, + SaveSelections = function(self, list, pn) + local found = false + for i = 1, #list do + if not found then + if list[i] == true then + local value = i + themeConfig:get_data().global.LeaderboardSlots = value + found = true + end + end + end + themeConfig:set_dirty() + themeConfig:save() + end + } + setmetatable(t, t) + return t +end +function DisplayPercent() + local t = { + Name = "DisplayPercent", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = false, + ExportOnChange = true, + Choices = {THEME:GetString("OptionNames", "Off"), THEME:GetString("OptionNames", "On")}, + LoadSelections = function(self, list, pn) + local pref = playerConfig:get_data(pn_to_profile_slot(pn)).DisplayPercent + if pref then + list[2] = true + else + list[1] = true + end + end, + SaveSelections = function(self, list, pn) + local value + value = list[2] + playerConfig:get_data(pn_to_profile_slot(pn)).DisplayPercent = value + playerConfig:set_dirty(pn_to_profile_slot(pn)) + playerConfig:save(pn_to_profile_slot(pn)) + end + } + setmetatable(t, t) + return t +end function NPSWindow() local t = { - Name = "NPSWindow"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = {"1","2","3","4","5"}; + Name = "NPSWindow", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = {"1","2","3","4","5"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().NPSDisplay.MaxWindow if pref then list[pref] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value for k,v in ipairs(list) do if v then value = k - end; - end; + end + end themeConfig:get_data().NPSDisplay.MaxWindow = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function SongPreview() local t = { - Name = "SongPreview"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = {"SM Style","osu! Style (Current)","osu! Style (Old)"}; + Name = "SongPreview", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = {"SM Style","osu! Style (Current)","osu! Style (Old)"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.SongPreview if pref then list[pref] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value for k,v in ipairs(list) do if v then value = k - end; - end; + end + end themeConfig:get_data().global.SongPreview = value themeConfig:set_dirty() themeConfig:save() THEME:ReloadMetrics() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t +end + +function AnimatedLeaderboard() + local t = { + Name = "AnimatedLeaderboard", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, + LoadSelections = function(self, list, pn) + local pref = themeConfig:get_data().global.AnimatedLeaderboard + if pref then + list[2] = true + else + list[1] = true + end + end, + SaveSelections = function(self, list, pn) + local value + if list[1] then + value = false + else + value = true + end + themeConfig:get_data().global.AnimatedLeaderboard = value + themeConfig:set_dirty() + themeConfig:save() + end + } + setmetatable( t, t ) + return t end function BannerWheel() local t = { - Name = "BannerWheel"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","On"}; + Name = "BannerWheel", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.BannerWheel if pref then list[2] = true else list[1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] then value = false else value = true - end; + end themeConfig:get_data().global.BannerWheel = value themeConfig:set_dirty() themeConfig:save() THEME:ReloadMetrics() - end; - }; - setmetatable( t, t ); - return t; + end + } + setmetatable( t, t ) + return t end function BareBone() local t = { - Name = "BareBone"; - LayoutType = "ShowAllInRow"; - SelectType = "SelectOne"; - OneChoiceForAllPlayers = true; - ExportOnChange = true; - Choices = { "Off","On"}; + Name = "BareBone", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, LoadSelections = function(self, list, pn) local pref = themeConfig:get_data().global.BareBone if pref then list[2] = true else list[1] = true - end; - end; + end + end, SaveSelections = function(self, list, pn) local value if list[1] then value = false else value = true - end; + end themeConfig:get_data().global.BareBone = value themeConfig:set_dirty() themeConfig:save() - end; - }; - setmetatable( t, t ); - return t; -end \ No newline at end of file + end + } + setmetatable( t, t ) + return t +end +function JudgementTween() + local t = { + Name = "JudgementTween", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, + LoadSelections = function(self, list, pn) + local pref = themeConfig:get_data().global.JudgementTween + if pref then + list[2] = true + else + list[1] = true + end + end, + SaveSelections = function(self, list, pn) + local value + if list[1] then + value = false + else + value = true + end + themeConfig:get_data().global.JudgementTween = value + themeConfig:set_dirty() + themeConfig:save() + end + } + setmetatable( t, t ) + return t +end +function UseAssetsJudgements() + local t = { + Name = "UseAssetsJudgements", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Native","Assets"}, + LoadSelections = function(self, list, pn) + local pref = themeConfig:get_data().global.UseAssetsJudgements + if pref then + list[2] = true + else + list[1] = true + end + end, + SaveSelections = function(self, list, pn) + local value + if list[1] then + value = false + else + value = true + end + themeConfig:get_data().global.UseAssetsJudgements = value + themeConfig:set_dirty() + themeConfig:save() + end + } + setmetatable( t, t ) + return t +end +function ComboTween() + local t = { + Name = "ComboTween", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, + LoadSelections = function(self, list, pn) + local pref = themeConfig:get_data().global.ComboTween + if pref then + list[2] = true + else + list[1] = true + end + end, + SaveSelections = function(self, list, pn) + local value + if list[1] then + value = false + else + value = true + end + themeConfig:get_data().global.ComboTween = value + themeConfig:set_dirty() + themeConfig:save() + end + } + setmetatable( t, t ) + return t +end +function ComboWords() + local t = { + Name = "ComboWords", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = { "Off","On"}, + LoadSelections = function(self, list, pn) + local pref = themeConfig:get_data().global.ComboWords + if pref then + list[2] = true + else + list[1] = true + end + end, + SaveSelections = function(self, list, pn) + local value + if list[1] then + value = false + else + value = true + end + themeConfig:get_data().global.ComboWords = value + themeConfig:set_dirty() + themeConfig:save() + end + } + setmetatable( t, t ) + return t +end \ No newline at end of file diff --git a/Scripts/10 Widgets.lua b/Scripts/10 Widgets.lua new file mode 100644 index 00000000..a12031ec --- /dev/null +++ b/Scripts/10 Widgets.lua @@ -0,0 +1,805 @@ +Widg = {} +Widg.defaults = {} +function fillNilTableFieldsFrom(table1, defaultTable) + for key, value in pairs(defaultTable) do + if table1[key] == nil then + table1[key] = defaultTable[key] + end + end +end +function checkColor(c) + if type(c) == "string" then + if string.sub(c, 1, 1) ~= "#" then + c = "#" .. c + end + if string.len(c) < 9 then + c = c .. string.rep("F", 9 - string.len(c)) + end + return color(c) + end + return c +end + +Widg.defaults.container = { + x = 0, + y = 0, + onInit = false, + content = false, + visible = true, + name = "Container" +} +Widg.Container = function(params) + fillNilTableFieldsFrom(params, Widg.defaults.container) + local container + container = + Def.ActorFrame { + Name = params.name, + InitCommand = function(self) + container.actor = self + self:xy(params.x, params.y):visible(params.visible) + if params.onInit then + params.onInit(self) + end + end + } + container.add = function(container, item) + container[#container + 1] = item + end + if params.content then + if params.content.Class then -- is an actor + container[#container + 1] = params.content + else -- assume its a table + container[#container + 1] = Def.ActorFrame(params.content) + end + end + return container +end + +Widg.defaults.label = { + x = 0, + y = 0, + scale = 1.0, + text = "Label", + name = "Common Normal", + width = false, + color = color("#FFFFFF"), + halign = 0.5, + valign = 0.5, + onInit = false +} +Widg.Label = function(params) + fillNilTableFieldsFrom(params, Widg.defaults.label) + params.color = checkColor(params.color) + + local initText = params.text + local label + label = + LoadFont(params.name) .. + { + Name = "Label", + InitCommand = function(self) + label.actor = self + self:xy(params.x, params.y):zoom(params.scale):halign(params.halign):valign(params.valign) + if type(params.width) == "number" then + self:maxwidth(params.width / params.scale) + end + self:settext(initText):diffuse(params.color) + if params.onInit then + params.onInit(self) + end + end + } + label.settext = function(label, text) + if label.actor then + label.actor:settext(text) + else + initText = text + end + end + label.GetText = function(label, text) + return label.actor and label.actor:GetText() or initText + end + return label +end + +Widg.defaults.rectangle = { + x = 0, + y = 0, + width = 100, + height = 100, + color = color("#FFFFFF"), + onClick = false, + onInit = false, + alpha = 1.0, + halign = 0.5, + valign = 0.5, + visible = true, + clickPolling = 0.3 +} +Widg.Rectangle = function(params) + fillNilTableFieldsFrom(params, Widg.defaults.rectangle) + params.color = checkColor(params.color) + local lastClick = -1 + local q + q = + Def.Quad { + InitCommand = function(self) + self:halign(params.halign):valign(params.valign):xy(params.x + params.width / 2, params.y + params.height / 2):zoomto( + params.width, + params.height + ):diffusealpha(params.alpha) + if params.onInit then + params.onInit(self) + end + self:visible(params.visible) + q.actor = self + end, + OnCommand = params.color and function(self) + self:diffuse(params.color):diffusealpha(params.alpha) + end or nil, + LeftClickMessageCommand = params.onClick and function(self) + if params.onClick and q:isOver() then + lastClick = os.clock() + params.onClick(self) + end + end or nil + } + q.isOver = function(self) + return os.clock() - lastClick > params.clickPolling and isOver(self.actor) + end + return q +end + +Widg.defaults.borders = { + x = 0, + y = 0, + color = color("#FFFFFF"), + width = 100, + height = 100, + borderWidth = 10, + onInit = false, + alpha = 1.0 +} +Widg.Borders = function(params) + fillNilTableFieldsFrom(params, Widg.defaults.borders) + params.color = checkColor(params.color) + local left = + Widg.Rectangle({width = params.borderWidth, height = params.height, color = params.color, alpha = params.alpha}) + local right = + Widg.Rectangle( + { + x = params.width - params.borderWidth, + width = params.borderWidth, + height = params.height, + color = params.color, + alpha = params.alpha + } + ) + local top = + Widg.Rectangle({width = params.width, height = params.borderWidth, color = params.color, alpha = params.alpha}) + local bottom = + Widg.Rectangle( + { + y = params.height - params.borderWidth, + width = params.width, + height = params.borderWidth, + color = params.color, + alpha = params.alpha + } + ) + local borders = + Def.ActorFrame { + InitCommand = function(self) + self:xy(params.x, params.y) + if params.onInit then + params.onInit(self) + end + end, + left, + top, + right, + bottom + } + borders.top = top + borders.left = left + borders.bottom = bottom + borders.right = right + return borders +end +local function highlight(self) + self:queuecommand("Highlight") +end + +Widg.defaults.borderedrect = { + x = 0, + y = 0, + color = "FFFFFF", + border = { + color = "000000", + width = 2 + }, + width = 100, + height = 100, + onInit = false, + alpha = 1.0, + visible = true +} +Widg.BorderedRect = function(params) + fillNilTableFieldsFrom(params, Widg.defaults.borderedrect) + params.color = checkColor(params.color) + params.border.color = checkColor(params.border.color) + return Widg.Container { + x = params.x, + y = params.y, + visible = params.visible, + onInit = params.onInit, + content = { + Widg.Borders { + width = params.width, + height = params.height, + alpha = params.alpha, + color = params.border.color + }, + Widg.Rectangle { + width = params.width, + height = params.height, + color = params.color, + borderWidth = params.border.width + } + } + } +end + +Widg.defaults.sprite = { + x = 0, + y = 0, + color = false, + onInit = false, + texture = false, + valign = 0.5, + halign = 0.5, + width = 0, + height = 0, + color = false +} +Widg.Sprite = function(params) + fillNilTableFieldsFrom(params, Widg.defaults.sprite) + params.color = checkColor(params.color) + local sprite + sprite = + Def.Sprite { + _Level = 1, + Texture = path, + InitCommand = function(self) + sprite.actor = self + self:xy(params.x, params.y):halign(params.halign):valign(params.valign) + if params.color then + self:diffuse(params.color) + end + if params.width > 0 and params.height > 0 then + self:zoomto(params.width, params.height) + end + if params.onInit then + params.onInit(self) + end + end + } + if params.texture then + sprite.Texture = ResolveRelativePath(THEME:GetPathG("", params.texture), 3) + end + return sprite +end +Widg.defaults.button = { + x = 0, + y = 0, + width = 50, + height = 20, + bgColor = color("#bb00bbFF"), + border = { + color = Color.Blue, + width = 2 + }, + highlight = { + color = color("#dd00ddFF"), + alpha = false + }, + onClick = false, + onInit = false, + onHighlight = false, + onUnhighlight = false, + alpha = 1.0, + text = "Button", + font = { + scale = 0.5, + name = "Common Large", + color = Color.White, + padding = { + x = 10, + y = 10 + } + }, + halign = 0.5, + valign = 0.5, + texture = false, + enabled = true +} + +Widg.Button = function(params) + fillNilTableFieldsFrom(params, Widg.defaults.button) + if params.highlight then + params.highlight.color = checkColor(params.highlight.color) + end + params.bgColor = checkColor(params.bgColor) + if params.font then + params.font.color = checkColor(params.font.color) + end + if params.border then + params.border.color = checkColor(params.border.color) + end + + local button + button = + Widg.Container { + onInit = function(self) + if params.onInit then + params.onInit(self) + end + if params.highlight then + self:SetUpdateFunction(highlight) + end + self.params = params + if not button.enabled then + button:Disable() + end + end + } + button.enabled = params.enabled + + button.sprite = + params.texture and + Widg.Sprite { + x = params.x, + color = params.bgColor, + y = params.y, + texture = "buttons/" .. params.texture, + width = params.width, + height = params.height, + halign = params.halign - 0.5, + valign = params.valign - 0.5 + } or + Def.ActorFrame {} + button.highlightSprite = + params.highlight and params.highlight.texture and + Widg.Sprite { + x = params.x, + color = params.highlight.color, + y = params.y, + texture = "buttons/" .. params.highlight.texture, + width = params.width, + height = params.height, + halign = params.halign - 0.5, + valign = params.valign - 0.5 + } or + Def.ActorFrame {} + + button.bg = + Widg.Rectangle { + x = params.x, + y = params.y, + width = params.width, + height = params.height, + color = params.bgColor, + visible = not (not params.texture), + alpha = params.texture and 0 or params.alpha, + onClick = params.onClick and function(s) + if button.enabled then + params.onClick(button) + end + end or false, + halign = params.halign, + valign = params.valign, + visible = not params.texture + } + button.bg.HighlightCommand = params.highlight and function(self) + local mainActor = params.texture and button.sprite.actor or self + local isOver = isOver(self) + if params.highlight.texture then + (button.highlightSprite.actor):visible(isOver) + end + if isOver then + if params.highlight.color then + mainActor:diffuse(params.highlight.color) + end + mainActor:diffusealpha(params.highlight.alpha or params.alpha or 1) + if params.onHighlight then + params.onHighlight(mainActor) + end + else + if params.bgColor then + mainActor:diffuse(params.bgColor) + end + mainActor:diffusealpha(params.alpha) + if params.onUnhighlight then + params.onUnhighlight(mainActor) + end + end + end or nil + + button.borders = + (params.texture or not params.border) and Def.ActorFrame {} or + Widg.Borders { + y = params.y + params.height * (0.5 - params.valign), + x = params.x + params.width * (0.5 - params.halign), + color = params.border.color, + width = params.width, + height = params.height, + borderWidth = params.border.width, + alpha = params.texture and 0 or params.alpha + } + + button.label = + Widg.Label { + x = params.x + params.width * (1 - params.halign), + y = params.y + params.height * (1 - params.valign), + scale = params.font.scale, + halign = params.font.halign, + text = params.text, + width = params.width - params.font.padding.x + } + + button.settext = function(button, text) + return (button.label):settext(text) + end + button.GetText = function(button) + return (button.label):GetText() + end + button.diffuse = function(button, color) + params.bgColor = color + return (button.bg.actor):diffuse(color) + end + button.Enable = function(button) + button.enabled = true + return (button.actor):visible(button.enabled) + end + button.Disable = function(button) + button.enabled = false + return (button.actor):visible(button.enabled) + end + + button:add(button.bg) + button:add(button.borders) + button:add(button.sprite) + button:add(button.highlightSprite) + button:add(button.label) + return button +end + +Widg.defaults.scrollable = { + width = 100, + height = 100, + content = false, + textureName = false, + x = 0, + y = 0, + halign = 0, + valign = 0, + onInit = false +} +Widg.scrollableCount = 0 +Widg.Scrollable = function(params) + fillNilTableFieldsFrom(params, Widg.defaults.scrollable) + local textureName = params.textureName or "ScrollableWidget" .. tostring(Widg.scrollableCount) + Widg.scrollableCount = Widg.scrollableCount + 1 + local content = params.content or Def.ActorFrame {} + local sprite = + Def.Sprite { + Texture = textureName, + InitCommand = function(self) + self:halign(0):valign(0):SetTextureFiltering(true) + end + } + local AFT = + Def.ActorFrameTexture { + InitCommand = function(self) + self:SetTextureName(textureName) + if params.width and params.width > 0 then + self:SetWidth(params.width) + end + if params.height and params.height > 0 then + self:SetHeight(params.height) + end + self:EnableAlphaBuffer(true) + self:EnableDepthBuffer(true) + self:EnableFloat(true) + self:SetTextureFiltering(true) + self:Create() + end, + Def.ActorFrame { + Name = "Draw", + content + } + } + local scrollable = + Def.ActorFrame { + InitCommand = function(self) + self:xy(params.x + params.halign * params.width, params.y + params.valign * params.height) + self.AFT = AFT + self.sprite = sprite + self.content = content + self:SetTextureFiltering(true) + if params.onInit then + params.onInit(self, content, AFT, sprite) + end + end, + AFT, + sprite + } + scrollable.content = content + return scrollable +end + +local function basicHandle(params) + local h + h = + Widg.Rectangle { + color = "00FF00", + width = params.width / 5, + height = params.height, + valign = params.valign + } + h.onValueChange = function(val) + h.actor:x(val * params.width / (params.max - params.min) - params.width * params.halign * 0.5) + end + return h +end +local function basicBar(params) + return Widg.Rectangle { + color = "FF0000", + width = params.width, + height = params.height, + halign = params.halign, + valign = params.valign + } +end +Widg.defaults.sliderBase = { + x = 0, + y = 0, + visible = true, + width = 100, + height = 30, + onClick = false, + color = color("#FFFFFFFF"), + onValueChangeEnd = false, -- Called when the mouse click is released + onValueChange = false, -- Recieves the value between min and max + handle = basicHandle, + bar = basicBar, + onInit = false, + defaultValue = 10, -- starting value + max = 100, + min = 0, + step = 1, + halign = 1, + valign = 1, + vertical = false, -- todo + isRange = false, -- todo + bindToTable = {} -- Since tables are passed by reference, update t.value with the slider value. + -- If range, value = {start=number, end=number} +} + +local function getRatioforAxis(mpos, pos, len, align) + -- for some reason this magic math works + -- it gives a number between 0 and 1 + -- its the percentage of the rectangle that + -- is to the left of the mouse + return (mpos - (pos + len * (1 - align))) / len + 0.5 +end +-- this returns the current value for the slider +local function getValue(mouse, params, slider) + local length = (params.max - params.min) + local ratio = + params.vertical and getRatioforAxis(mouse.y, getTrueY(slider), params.height, params.valign) or + getRatioforAxis(mouse.x, getTrueX(slider), params.width, params.halign) + return math.round((ratio * length + params.min) / params.step) * params.step +end +Widg.SliderBase = function(params) + fillNilTableFieldsFrom(params, Widg.defaults.sliderBase) + params.color = checkColor(params.color) + local bar = params.bar(params) + local handle = params.handle(params) + local updateFunction + local container = + Widg.Container { + visible = params.visible, + x = params.x, + y = params.y, + onInit = function(container) + handle.onValueChange(params.defaultValue) + container:SetUpdateFunction(updateFunction) + if params.onInit then + params.onInit(container) + end + end + } + if params.range and type(params.defaultValue) ~= "table" then + params.defaultValue = {params.defaultValue, params.defaultValue} + end + local t = params.bindToTable + t.value = defaultValue + container.value = t.value + container:add(bar) + container:add(handle) + local clicked = false + local rectangle = + Widg.Rectangle { + width = params.width, + height = params.height, + halign = params.halign, + valign = params.valign, + onClick = function(rectangle) + clicked = true + end, + visible = false + } + container:add(rectangle) + updateFunction = function(container) + if clicked then + if isOver(rectangle.actor) and INPUTFILTER:IsBeingPressed("Mouse 0", "Mouse") then + local mouse = getMousePosition() + t.value = getValue(mouse, params, container) + container.value = t.value + if params.onValueChange then + params.onValueChange(t.value) + end + if handle.onValueChange then + handle.onValueChange(t.value) + end + if bar.onValueChange then + bar.onValueChange(t.value) + end + else + clicked = false + if params.onValueChangeEnd then + params.onValueChangeEnd(t.value) + end + if bar.onValueChange then + bar.onValueChange(t.value) + end + if bar.onValueChangeEnd then + bar.onValueChangeEnd(t.value) + end + end + end + end + return container +end + +local function basicSelection(choice, params) + return Widg.Button { + y = 0, + text = choice, + width = params.width, + color = params.selectionColor, + border = false, + height = params.itemHeight, + highlight = {color = params.hoverColor}, + alpha = 0.8 + } +end +local function basicItem(choice, params) + return Widg.Button { + text = choice, + width = params.width, + height = params.itemHeight, + color = params.itemColor, + border = false, + alpha = 1, + highlight = {color = params.hoverColor} + } +end +Widg.defaults.comboBox = { + x = 0, + y = 0, + itemHeight = 20, + maxDisplayItems = 5, + width = 50, + onSelectionChanged = false, -- (newchoice, oldchoice) + onInit = false, + item = basicItem, + selection = basicSelection, -- must understand :settext + commands = {}, + selectionColor = Color.Black, + hoverColor = Color.Blue, + itemColor = Color.Black, + choices = {"default"}, + choice = false, + numitems = false, + scrollable = false +} +Widg.ComboBox = function(params, updateActor) + fillNilTableFieldsFrom(params, Widg.defaults.comboBox) + params.selectionColor = checkColor(params.selectionColor) + params.itemColor = checkColor(params.itemColor) + params.hoverColor = checkColor(params.hoverColor) + + local combobox = + Widg.Container { + x = params.x - params.width / 2, + y = params.y - params.itemHeight / 2, + onInit = params.onInit, + visible = params.visible + } + fillNilTableFieldsFrom(combobox, params.commands) + + if not params.numitems then + params.numitems = #(params.choices) + end + combobox.choices = params.choices + combobox.droppedDown = false + combobox.selected = 1 + if params.choice then + for i, v in ipairs(params.choices) do + if v == params.choice then + combobox.selected = i + end + end + end + combobox.items = Widg.Container {visible = false} + combobox.selection = Widg.Container {} + combobox.selection.graphic = params.selection(combobox.choices[combobox.selected], params) + combobox.selection:add(combobox.selection.graphic) + combobox.selection:add( + Widg.Rectangle { + visible = false, + width = params.width, + height = params.itemHeight, + onClick = function(self) + combobox.droppedDown = not combobox.droppedDown + local items = combobox.items.actor + items:visible(combobox.droppedDown) + end + } + ) + + for i = 1, params.numitems do + (combobox.items):add( + Widg.Container { + y = i * params.itemHeight, + content = { + params.item(combobox.choices[i], params), + Widg.Rectangle { + width = params.width, + height = params.itemHeight, + visible = false, + onClick = function(self) + if combobox.droppedDown then + local g = combobox.selection.graphic + g:settext(combobox.choices[i]) + if params.onSelectionChanged then + params.onSelectionChanged(combobox.choices[i], combobox.choices[combobox.selected]) + end + combobox.selected = i + combobox.droppedDown = false + local items = combobox.items.actor + items:visible(combobox.droppedDown) + end + end + } + } + } + ) + end + + if params.scrollable then + combobox:add( + Widg.Scrollable { + width = params.width, + height = params.itemHeight * (params.numitems + 1), + content = combobox.items + } + ) + else + combobox:add(combobox.items) + end + combobox:add(combobox.selection) + return combobox +end diff --git a/Scripts/Avatar.lua b/Scripts/Avatar.lua index 62461dde..ea12d2b0 100644 --- a/Scripts/Avatar.lua +++ b/Scripts/Avatar.lua @@ -6,8 +6,8 @@ local function addProfileFromGUID(GUID) avatarConfig:get_data().avatar[GUID] = avatarConfig:get_data().avatar.default avatarConfig:set_dirty() avatarConfig:save() - end; -end; + end +end function ProfileManager.GetAvatarFolderPath() return "Themes/"..THEME:GetCurThemeName().."/Graphics/Player avatar/" @@ -26,19 +26,19 @@ function ProfileManager.GetAvatarName(self, pn) -- make the new config for the profile and return the default image. fileName = avatarConfig:get_data().avatar.default addProfileFromGUID(GUID) - end; + end if FILEMAN:DoesFileExist(self:GetAvatarFolderPath()..fileName) then return fileName else return "_fallback.png" - end; -end; + end +end function ProfileManager.GetAvatarPath(self, pn) return string.format("%s%s",self:GetAvatarFolderPath(),self:GetAvatarName(pn)) -end; +end function ProfileManager.GetAllAvatarNames() local imgTypes = {".jpg",".png",".gif",".jpeg"} diff --git a/Scripts/ClearType.lua b/Scripts/ClearType.lua index f9de0e35..91a537b8 100644 --- a/Scripts/ClearType.lua +++ b/Scripts/ClearType.lua @@ -187,8 +187,10 @@ local function getClearLevel (pn,steps,score) elseif missCount == 1 then return 8 -- MF + elseif missCount < 10 and missCount > 1 then + return 9 -- SDCB end - + return 12 -- Clear end @@ -236,8 +238,8 @@ function getHighestClearType(pn,steps,scoreList,ignore) hScore = scoreList[i] if hScore ~= nil then highest = math.min(highest,getClearLevel(pn,steps,hScore)) - end; - end; + end + end i = i+1 end end @@ -249,25 +251,25 @@ function getClearTypeLampQuad(width, height) local t = Def.ActorFrame{ SetClearTypeCommand = function(self, params) self:RunCommandsOnChildren(function(self) self:playcommand("Set", params) end) - end; + end } t[#t+1] = Def.Quad{ InitCommand = function(self) self:zoomto(width, height) - end; + end, SetCommand = function(self, params) if params then self:diffuse(getClearTypeColor(params.clearType)) end - end; + end } t[#t+1] = Def.Quad{ InitCommand = function(self) self:zoomto(width, height) - end; + end, SetCommand = function(self, params) if not params then return @@ -284,7 +286,7 @@ function getClearTypeLampQuad(width, height) self:effectcolor1(color("1,1,1,0")) self:effecttiming(2,1,0,0) end - end; + end } return t diff --git a/Scripts/Levels.lua b/Scripts/Levels.lua index d742a5d0..349367f8 100644 --- a/Scripts/Levels.lua +++ b/Scripts/Levels.lua @@ -1,8 +1,7 @@ -- STEPMANIA RPG - MINUS THE ROLEPLAY PART local curExp = { - PlayerNumber_P1, - PlayerNumber_P2 + PlayerNumber_P1 } diff --git a/Scripts/Quotes.lua b/Scripts/Quotes.lua index be092dc4..9afcee11 100644 --- a/Scripts/Quotes.lua +++ b/Scripts/Quotes.lua @@ -5,7 +5,59 @@ -- Also (hopefully helpful) tips regarding the game/theme,etc. ----------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------- -local Tips = {""} +local Tips = { + "Did you know Ctrl + S saves your profile?", + "Did you know Ctrl + F adds/removes a song from your favorites?", + "Did you know you can login to automatically upload your scores to EtternaOnline?", + "Did you know you can play multiplayer with an EtternaOnline account?", + "Did you know most players hang out in the EtternaOnline discord?", + "Did you know you can change the game volume in the debug menu (F3)?", + "Did you know you can change the global offset in gameplay using Shift + F11/F12?", + "Put a picture into the Assets/Avatars folder to be able to use it ingame.", + "You can view a leaderboard for any ranked chart if you are logged in.", + "Did you know Ctrl + Enter focuses the multiplayer chat?", + "Did you know Insert toggles the multiplayer chat?", + "Did you know EtternaOnline houses a large database of Noteskins and Toasties?", + "Did you know you can move gameplay elements around if you turn on Customize Gameplay?", + "You can immediately exit the group on the song wheel by pressing Up + Down", + "You can use your own Early/Late Judgment skin in the assets folder!", + "The Theme Options contains many useful customization options.", + "You can suggest features for Etterna or Spawncamping-wallhack on the EtternaOnline discord", + "You can use the numbers on your keyboard for shortcuts to the various tabs", + "Use Ctrl + 4 for a shortcut to the search menu.", + "Click on the current sort in the top right to search.", + "You can toggle common pack filtering in multiplayer in the Filtering Tab.", + "You can right click the Notefield in the Chart Preview to pause it.", + "You can use the scroll wheel on the density graph in the Chart Preview to seek.", + "You can press F3 + F5 + T to crash the game", + "You can toggle pitch rates in the Advanced Options.", + "You can use the mouse to move elements in Customize Gameplay. Left click to teleport an element.", + "You can turn off the Multiplayer Gameplay Leaderboard in Network Options.", + "You can modify the color of most visual elements in the Color Config found on the Title Screen.", + "You can use the mouse to navigate nearly every menu in the game.", + "You can change the rate of Practice using the same buttons you usually use to change rates.", + "You can change rates in Music Select using EffectUp/EffectDown.", + "You can click the scroll bar on the Music Wheel to teleport wheel positions.", + "You can paste your clipboard into most text entry fields in the game.", + "You can use Alt + Enter to toggle fullscreen.", + "You can hold Tab to speed up most animations in the game.", + "You can hold Enter to exit the input test screen.", + "You can unbind any button by rebinding its default to a button you never use.", + "Did you know pressing / automatically focuses the chat for quick command use?", + "You can press the sequence 'Up Down Up Down' to open the sorting menu on the song wheel.", + "You can import most of your settings from Til Death by copying your playerconfig.lua from the respective folder.", + "Press Up to reset any judge conversions you do on the evaluation screen.", + "Press EffectUp/EffectDown to convert judges on the evaluation screen.", + "A vacuous goal is a goal set for a score you have already obtained.", + "The dividers on the song wheel change colors depending on the goals you set.", + "Press Ctrl + Q to load any new songs added to the game.", + "Press Ctrl + Shift + R to reload a specific song from the disk.", + "Press Ctrl + Shift + P to reload a whole pack from the disk.", + "Click your avatar to change it.", + "Most lists allow using the scroll wheel to browse through them. Alternatively, use Left and Right.", + "The only way to change your player options in multiplayer is by clicking the Player Options button.", + +} diff --git a/Scripts/Scores.lua b/Scripts/Scores.lua index 0c2489ff..28af1d3c 100644 --- a/Scripts/Scores.lua +++ b/Scripts/Scores.lua @@ -237,7 +237,7 @@ function getUsedRates(rtTable) if rtTable ~= nil then for k,v in pairs(rtTable) do rates[#rates+1] = k - end; + end table.sort(rates,function(a,b) a=a:gsub("x","") b=b:gsub("x","") return a= (y-(vAlign*h))) and (mouseY <= ((y+h)-(vAlign*h))) return (withinX and withinY) -end; +end @@ -124,25 +124,27 @@ function quadButton(z) local t = Def.Quad{ InitCommand= function(self) self:z(z) - end; + end, OnCommand = function(self) local top = SCREENMAN:GetTopScreen() - topName = top:GetName() - end; + if top ~= nil then + topName = top:GetName() + end + end, MouseLeftClickMessageCommand = function(self) if self:isOver() then BUTTON:addPressedActors(self, topName, "DeviceButton_left mouse button") end - end; + end, MouseRightClickMessageCommand = function(self) if self:isOver() then BUTTON:addPressedActors(self, topName, "DeviceButton_right mouse button") end - end; + end, TopPressedCommand = function(self) - end; + end, } return t @@ -158,7 +160,7 @@ function checkbox(z, checked) local t = Def.ActorFrame{ InitCommand = function(self) self:playcommand("Toggle") - end; + end, ToggleCommand = function(self) if checked then checked = false @@ -169,26 +171,26 @@ function checkbox(z, checked) self:playcommand("Check") self:RunCommandsOnChildren(function(self) self:playcommand("Check") end) end - end; + end, CheckCommand = function(self) - end; + end, UncheckCommand = function(self) - end; + end } t[#t+1] = Def.Quad{ InitCommand = function(self) self:zoomto(zoom*100,zoom*100) self:diffuse(color("#000000")):diffusealpha(0.8) - end; + end } t[#t+1] = quadButton(z) .. { InitCommand = function(self) self:zoomto(zoom*100,zoom*100) self:diffuse(color("#FFFFFF")):diffusealpha(0) - end; + end, TopPressedCommand = function(self, params) if params.input == "DeviceButton_left mouse button" then self:GetParent():playcommand("Toggle") @@ -197,25 +199,25 @@ function checkbox(z, checked) self:smooth(0.3) self:diffusealpha(0) end - end; + end } t[#t+1] = LoadActor(THEME:GetPathG("", "_x"))..{ InitCommand = function(self) self:zoom(zoom) - end; + end, CheckCommand = function(self) self:finishtweening() self:smooth(0.1) self:zoom(zoom) self:diffusealpha(1) - end; + end, UncheckCommand = function(self) self:finishtweening() self:smooth(0.1) self:zoom(0) self:diffusealpha(0) - end; + end } return t diff --git a/Scripts/WifeSundries.lua b/Scripts/WifeSundries.lua index 626d30b9..5c26cb30 100644 --- a/Scripts/WifeSundries.lua +++ b/Scripts/WifeSundries.lua @@ -42,10 +42,10 @@ end function changeMusicRate(amount) local curRate = getCurRateValue() local newRate = curRate + amount - if newRate <= 3 and newRate >= 0.75 then + if newRate <= 3 and newRate >= 0.7 then GAMESTATE:GetSongOptionsObject('ModsLevel_Preferred'):MusicRate(curRate+amount) GAMESTATE:GetSongOptionsObject('ModsLevel_Song'):MusicRate(curRate+amount) GAMESTATE:GetSongOptionsObject('ModsLevel_Current'):MusicRate(curRate+amount) - MESSAGEMAN:Broadcast("CurrentRateChanged", {rate = newRate}) + MESSAGEMAN:Broadcast("CurrentRateChanged", {rate = newRate, oldRate = curRate}) end end \ No newline at end of file diff --git a/ThemeInfo.ini b/ThemeInfo.ini index 0b79bbd7..ceba2e23 100644 --- a/ThemeInfo.ini +++ b/ThemeInfo.ini @@ -1,3 +1,3 @@ [ThemeInfo] -DisplayName=spawncamping-wallhack (SM5) +DisplayName=spawncamping-wallhack (Etterna) Author=Prim \ No newline at end of file diff --git a/metrics.ini b/metrics.ini index 146e3a02..ca2ea01b 100644 --- a/metrics.ini +++ b/metrics.ini @@ -20,18 +20,6 @@ AutoSetStyle=true ShowComboAt=1 #ShowComboAt=HitCombo() ShowMissesAt=MissCombo() -# Shrink and Grow the combo, DDR Style -NumberMinZoom=0.4 -NumberMaxZoom=0.5 -NumberMaxZoomAt=100 -# -LabelMinZoom=0.75*0.75 -LabelMaxZoom=0.75*0.75 -# Things the combo does when you bang on it, and what the text does -PulseCommand=%function(self,param) self:stoptweening(); self:zoom(1.125*param.Zoom); self:linear(0.05); self:zoom(param.Zoom); end -PulseLabelCommand=%function(self,param) self:stoptweening(); self:zoom(param.LabelZoom); self:linear(0.05); self:zoom(param.LabelZoom); end -NumberOnCommand=y,240-216-1.5;shadowlength,1;halign,1;valign,1;skewx,-0.125;zoom,0.5; -LabelOnCommand=x,6;y,22.5;shadowlength,1;zoom,0.75;diffusebottomedge,color("0.75,0.75,0.75,1");halign,0;valign,1 [ScreenWithMenuElements] ShowHeader = true @@ -81,17 +69,7 @@ CursorOnCommand= CursorOffCommand= KeysInitCommand=zoom,0.8;shadowlength,0 -[Judgment] -# New # -JudgmentOnCommand=y,20; - -# Things the judgment does when you bang on it. -JudgmentW1Command=shadowlength,0;diffusealpha,1;zoom,1.3;linear,0.05;zoom,1;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0;glowblink;effectperiod,0.05;effectcolor1,color("1,1,1,0");effectcolor2,color("1,1,1,0.25") -JudgmentW2Command=shadowlength,0;diffusealpha,1;zoom,1.3;linear,0.05;zoom,1;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0 -JudgmentW3Command=shadowlength,0;diffusealpha,1;zoom,1.2;linear,0.05;zoom,1;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0; -JudgmentW4Command=shadowlength,0;diffusealpha,1;zoom,1.1;linear,0.05;zoom,1;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0; -JudgmentW5Command=shadowlength,0;diffusealpha,1;zoom,1.0;vibrate;effectmagnitude,4,8,8;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0 -JudgmentMissCommand=shadowlength,0;diffusealpha,1;zoom,1;linear,0.8;sleep,0.8;linear,0.1;zoomy,0.5;zoomx,2;diffusealpha,0 +PlayMusic=false [NoteField] ShowBoard=true @@ -127,9 +105,10 @@ ScrollerTransform=function(self,offset,itemIndex,numItems) \ self:y(20*(itemIndex-(numItems-1)/2)); \ end; \ -ChoiceNames="GameStart,Options,Edit,Color,GitHub,Exit" +ChoiceNames="GameStart,Multi,Options,AV,Color,GitHub,Exit" ChoiceColor="screen,ScreenColorChange;text,ColorChange" -ChoiceGitHub="urlnoexit,https://github.com/ca25nada/spawncamping-wallhack;text,GitHub" +ChoiceMulti="text,Multi;applydefaultoptions;screen,"..Branch.MultiScreen() +ChoiceGitHub="urlnoexit,https://github.com/poco0317/spawncamping-wallhack;text,GitHub" [ScreenOptions] @@ -145,10 +124,6 @@ ExplanationP1X=SCREEN_CENTER_X-256-20 ExplanationP1Y=SCREEN_CENTER_Y+174 ExplanationP1OnCommand=shadowlength,1;wrapwidthpixels,256/0.5;zoom,0.5;halign,0;cropright,1;linear,0.5;cropright,0 ExplanationP1OffCommand= -ExplanationP2X=SCREEN_CENTER_X+256+20 -ExplanationP2Y=SCREEN_CENTER_Y+174 -ExplanationP2OnCommand=shadowlength,1;wrapwidthpixels,256/0.5;zoom,0.5;halign,1;cropright,1;linear,0.5;cropright,0 -ExplanationP2OffCommand= ExplanationTogetherX=SCREEN_CENTER_X ExplanationTogetherY=SCREEN_CENTER_Y+184 ExplanationTogetherOnCommand=stoptweening;shadowlength,0;zoom,0.75;wrapwidthpixels,(SCREEN_WIDTH*0.9375)*1.25;cropright,1;linear,0.5;cropright,0 @@ -240,10 +215,10 @@ Fallback="ScreenWithMenuElements" PrevScreen="ScreenTitleMenu" CodeNames="ColorUp,ColorDown,ColorLeft,ColorRight,ColorCancel,ColorStart" -CodeColorUp="Up" -CodeColorDown="Down" -CodeColorLeft="Left" -CodeColorRight="Right" +CodeColorUp="MenuUp" +CodeColorDown="MenuDown" +CodeColorLeft="MenuLeft" +CodeColorRight="MenuRight" CodeColorCancel="Back" CodeColorStart="Start" @@ -253,10 +228,10 @@ Fallback="ScreenWithMenuElements" PrevScreen="ScreenTitleMenu" CodeNames="ColorUp,ColorDown,ColorLeft,ColorRight,ColorCancel,ColorStart" -CodeColorUp="Up" -CodeColorDown="Down" -CodeColorLeft="Left" -CodeColorRight="Right" +CodeColorUp="MenuUp" +CodeColorDown="MenuDown" +CodeColorLeft="MenuLeft" +CodeColorRight="MenuRight" CodeColorCancel="Back" CodeColorStart="Start" @@ -272,6 +247,12 @@ Fallback="ScreenWithMenuElements" PrevScreen="ScreenSelectMusic" PlayMusic=false +[ScreenNetMusicInfo] +Class="ScreenWithMenuElements" +Fallback="ScreenWithMenuElements" +PrevScreen="ScreenSelectMusic" +PlayMusic=false + [ScreenGroupInfo] Class="ScreenWithMenuElements" Fallback="ScreenWithMenuElements" @@ -290,6 +271,42 @@ Fallback="ScreenWithMenuElements" PrevScreen="ScreenSelectMusic" PlayMusic=false +[ScreenFiltering] +Class="ScreenWithMenuElements" +Fallback="ScreenWithMenuElements" +PrevScreen="ScreenSelectMusic" +PlayMusic=false + +[ScreenFileTagManager] +Class="ScreenWithMenuElements" +Fallback="ScreenWithMenuElements" +PrevScreen="ScreenSelectMusic" +PlayMusic=false + +[ScreenChartLeaderboard] +Class="ScreenWithMenuElements" +Fallback="ScreenWithMenuElements" +PrevScreen="ScreenSelectMusic" +PlayMusic=false + +[ScreenNetChartLeaderboard] +Class="ScreenWithMenuElements" +Fallback="ScreenWithMenuElements" +PrevScreen="ScreenSelectMusic" +PlayMusic=false + +[ScreenChartPreview] +Class="ScreenWithMenuElements" +Fallback="ScreenWithMenuElements" +PrevScreen="ScreenSelectMusic" +PlayMusic=false + +[ScreenGoalManager] +Class="ScreenWithMenuElements" +Fallback="ScreenWithMenuElements" +PrevScreen="ScreenSelectMusic" +PlayMusic=false + [ScreenPlaylistInfo] Class="ScreenWithMenuElements" Fallback="ScreenWithMenuElements" @@ -417,10 +434,9 @@ end; \ [ScreenPlayerOptions] PlayerNameplateP1X= PlayerNameplateP1Y= -PlayerNameplateP2X= -PlayerNameplateP2Y= -LineNames="1,Rate,8,RS,14,2,3A,3B,4,5,R1,R2,7,9,10,11,12,13,SF,JT,AST,GST,GT,PM,EB,LC,CH,NPS,16,LD,JD,BG,Fail,Score" +LineNames="1,Rate,CG,PRAC,8,RS,14,2,3A,3B,4,5,R1,R2,7,9,10,13,SF,LDB,DispPct,JT,TTT,TTG,TTM,EB,LC,CH,NPS,16,LD,JD,BG,BGB,Fail" +Line10="list,Mines" LineSF="lua,OptionRowScreenFilter()" LineJT="lua,JudgeType()" LineAST="lua,AvgScoreType()" @@ -435,44 +451,82 @@ LineRate="list,Rate" LineBG="list,Background" LineFail="list,Fail" LineScore="list,SaveScores" -LineRS="list,ReceptorSize" +LineRS="lua,ReceptorSize()" LineLD="conf,LifeDifficulty" LineJD="conf,TimingWindowScale" +LineCG="lua,CustomizeGameplay()" +LineBGB="conf,BGBrightness" +LineDispPct="lua,DisplayPercent()" +LineTTT="lua,TargetTracker()" +LineTTG="lua,TargetGoal()" +LineTTM="lua,TargetTrackerMode()" +LineLDB="lua,LeaderBoard()" NextScreen="ScreenGameplay" [ScreenOptionsMaster] +Mines="2" +MinesDefault="mod, no nomines, no mines" +Mines,1="mod,nomines;name,Off" +Mines,2="name,On" + +Rate="47;together" +RateDefault="mod,1.0xMusic;mod,no haste" +Rate,1="mod,0.7xMusic;name,0.7x" +Rate,2="mod,0.75xMusic;name,0.75x" +Rate,3="mod,0.8xMusic;name,0.8x" +Rate,4="mod,0.85xMusic;name,0.85x" +Rate,5="mod,0.9xMusic;name,0.9x" +Rate,6="mod,0.95xMusic;name,0.95x" +Rate,7="mod,1.0xMusic;name,1.0x" +Rate,8="mod,1.05xMusic;name,1.05x" +Rate,9="mod,1.1xMusic;name,1.1x" +Rate,10="mod,1.15xMusic;name,1.15x" +Rate,11="mod,1.2xMusic;name,1.2x" +Rate,12="mod,1.25xMusic;name,1.25x" +Rate,13="mod,1.3xMusic;name,1.3x" +Rate,14="mod,1.35xMusic;name,1.35x" +Rate,15="mod,1.4xMusic;name,1.4x" +Rate,16="mod,1.45xMusic;name,1.45x" +Rate,17="mod,1.5xMusic;name,1.5x" +Rate,18="mod,1.55xMusic;name,1.55x" +Rate,19="mod,1.6xMusic;name,1.6x" +Rate,20="mod,1.65xMusic;name,1.65x" +Rate,21="mod,1.7xMusic;name,1.7x" +Rate,22="mod,1.75xMusic;name,1.75x" +Rate,23="mod,1.8xMusic;name,1.8x" +Rate,24="mod,1.85xMusic;name,1.85x" +Rate,25="mod,1.9xMusic;name,1.9x" +Rate,26="mod,1.95xMusic;name,1.95x" +Rate,27="mod,2.0xMusic;name,2.0x" +Rate,28="mod,2.05xMusic;name,2.05x" +Rate,29="mod,2.1xMusic;name,2.1x" +Rate,30="mod,2.15xMusic;name,2.15x" +Rate,31="mod,2.2xMusic;name,2.2x" +Rate,32="mod,2.25xMusic;name,2.25x" +Rate,33="mod,2.3xMusic;name,2.3x" +Rate,34="mod,2.35xMusic;name,2.35x" +Rate,35="mod,2.4xMusic;name,2.4x" +Rate,36="mod,2.45xMusic;name,2.45x" +Rate,37="mod,2.5xMusic;name,2.5x" +Rate,38="mod,2.55xMusic;name,2.55x" +Rate,39="mod,2.6xMusic;name,2.6x" +Rate,40="mod,2.65xMusic;name,2.6x" +Rate,41="mod,2.7xMusic;name,2.7x" +Rate,42="mod,2.75xMusic;name,2.75x" +Rate,43="mod,2.8xMusic;name,2.8x" +Rate,44="mod,2.85xMusic;name,2.85x" +Rate,45="mod,2.9xMusic;name,2.9x" +Rate,46="mod,2.95xMusic;name,2.95x" +Rate,47="mod,3.0xMusic;name,3.0x" + EffectsReceptor="4;selectmultiple" EffectsReceptorDefault="mod,no confusion,no invert,no flip,no xmode" EffectsReceptor,1="mod,confusion;name,Confusion" EffectsReceptor,2="mod,invert;name,Invert" EffectsReceptor,3="mod,Flip;name,Flip" EffectsReceptor,4="mod,45% xmode;name,XMode" -ReceptorSize="21" -ReceptorSizeDefault="mod,no mini" -ReceptorSize,1="mod,mini;name,50%" -ReceptorSize,2="mod,90% mini;name,55%" -ReceptorSize,3="mod,80% mini;name,60%" -ReceptorSize,4="mod,70% mini;name,65%" -ReceptorSize,5="mod,60% mini;name,70%" -ReceptorSize,6="mod,50% mini;name,75%" -ReceptorSize,7="mod,40% mini;name,80%" -ReceptorSize,8="mod,30% mini;name,85%" -ReceptorSize,9="mod,20% mini;name,90%" -ReceptorSize,10="mod,10% mini;name,95%" - -ReceptorSize,11="mod,no mini;name,100%" -ReceptorSize,12="mod,-10% mini;name,105%" -ReceptorSize,13="mod,-20% mini;name,110%" -ReceptorSize,14="mod,-30% mini;name,115%" -ReceptorSize,15="mod,-40% mini;name,120%" -ReceptorSize,16="mod,-50% mini;name,125%" -ReceptorSize,17="mod,-60% mini;name,130%" -ReceptorSize,18="mod,-70% mini;name,135%" -ReceptorSize,19="mod,-80% mini;name,140%" -ReceptorSize,20="mod,-90% mini;name,145%" -ReceptorSize,21="mod,-100% mini;name,150%" [ScreenEvaluation] @@ -492,11 +546,6 @@ GraphDisplayP1X= GraphDisplayP1Y= GraphDisplayP1OnCommand= GraphDisplayP1OffCommand= -#~~~~~~~~~~~~~~# -GraphDisplayP2X= -GraphDisplayP2Y= -GraphDisplayP2OnCommand= -GraphDisplayP2OffCommand= # ComboGraph ShowComboGraph=true @@ -505,11 +554,7 @@ ComboGraphP1X=0 ComboGraphP1Y=80 ComboGraphP1OnCommand= ComboGraphP1OffCommand= -#~~~~~~~~~~~~~~# -ComboGraphP2X=0 -ComboGraphP2Y=80 -ComboGraphP2OnCommand= -ComboGraphP2OffCommand= + #hotvalue is now the new dangerthreshold huehuehue [LifeMeterBar] @@ -534,50 +579,21 @@ OverY=0 # ~ = Released # + = At The Same Time [ScreenGameplay] -CodeNames="LaneUp,LaneDown,SpeedUp,SpeedDown,ReleaseUp,ReleaseDown,Pause" +CodeNames="LaneUp,LaneDown,SpeedUp,SpeedDown,ReleaseUp,ReleaseDown" CodeSpeedUp="EffectUp" CodeSpeedDown="EffectDown" CodeLaneUp="@Select-EffectUp" CodeLaneDown="@Select-EffectDown" CodeReleaseUp="~EffectUp" CodeReleaseDown="~EffectDown" -CodePause="Select,Select" -UnpauseWithStart=false SelectSkipsSong=false LifeP1X= LifeP1Y= LifeP1OnCommand=visible,false; -LifeP2X= -LifeP2Y= -LifeP2OnCommand=visible,false; - ScoreP1OnCommand=visible,false; -ScoreP2OnCommand=visible,false; - -# online scoreboard -# P1 is used when the only player is P2 -ScoreboardC1P1X=250 -ScoreboardC1P1Y=50 -ScoreboardC1P1OnCommand=zoom,0.4;strokecolor,Color("Outline");shadowlength,1 -ScoreboardC2P1X=190 -ScoreboardC2P1Y=50 -ScoreboardC2P1OnCommand=zoom,0.4;strokecolor,Color("Outline");shadowlength,1 -ScoreboardC3P1X=140 -ScoreboardC3P1Y=50 -ScoreboardC3P1OnCommand=zoom,0.4;strokecolor,Color("Outline");shadowlength,1 -# P2 is used when the only player is P1 -ScoreboardC1P2X=SCREEN_WIDTH-250 -ScoreboardC1P2Y=50 -ScoreboardC1P2OnCommand=zoom,0.4;strokecolor,Color("Outline");shadowlength,1 -ScoreboardC2P2X=SCREEN_WIDTH-190 -ScoreboardC2P2Y=50 -ScoreboardC2P2OnCommand=zoom,0.4;strokecolor,Color("Outline");shadowlength,1 -ScoreboardC3P2X=SCREEN_WIDTH-140 -ScoreboardC3P2Y=50 -ScoreboardC3P2OnCommand=zoom,0.4;strokecolor,Color("Outline");shadowlength,1 MinSecondsToStep=5.0 MinSecondsToMusic=5.0 @@ -615,9 +631,6 @@ BodyWidth=SCREEN_CENTER_X-WideScale(get43size(40),40) [ComboGraphP1] Fallback="ComboGraph" -[ComboGraphP2] -Fallback="ComboGraph" - [ScreenOptionsService] AllowOperatorMenuButton=false @@ -627,14 +640,14 @@ Fallback="ScreenOptionsSimpleService" NextScreen=Branch.AfterInit() PrevScreen=Branch.AfterInit() -LineNames="GameType,GraphicSound,KeyConfig,Theme,Arcade,InputOptions,SoundGraphics,Profiles,Network,Advanced,Reload" +LineNames="GameType,GraphicSound,KeyConfig,Theme,InputOptions,SoundGraphics,Profiles,Network,Advanced" LineTheme="gamecommand;screen,ScreenOptionsTheme;name,Theme Options" [ScreenOptionsTheme] Fallback="ScreenOptionsServiceChild" NextScreen="ScreenOptionsService" PrevScreen="ScreenOptionsService" -LineNames="DefaultScore,TipType,SongBGEnabled,EvalBGType,SongBGMouseEnabled,Particles,RateSort,HelpMenu,NPSWindow,MeasureLines,ProgressBar,SongPreview,BannerWheel,BareBone" +LineNames="TipType,SongBGEnabled,EvalBGType,SongBGMouseEnabled,Particles,RateSort,NPSWindow,MeasureLines,LDS,LDA,ProgressBar,SongPreview,BannerWheel,PIT,EvalSB,BareBone,JT,JA,CT,CW" LineDefaultScore="lua,DefaultScoreType()" LineTipType="lua,TipType()" LineSongBGEnabled="lua,SongBGEnabled()" @@ -649,66 +662,29 @@ LineProgressBar="lua,ProgressBar()" LineSongPreview="lua,SongPreview()" LineBannerWheel="lua,BannerWheel()" LineBareBone="lua,BareBone()" +LineJA="lua,UseAssetsJudgements()" +LineJT="lua,JudgementTween()" +LineCT="lua,ComboTween()" +LineCW="lua,ComboWords()" +LineEvalSB="lua,EvalScoreboard()" +LinePIT="lua,PlayerInfoType()" +LineLDS="lua,LeaderboardSlots()" +LineLDA="lua,AnimatedLeaderboard()" [ScreenThemeColorChange] Fallback="ScreenTextEntry" - -[ScreenNetSelectBase] -ChatInputBoxX=SCREEN_CENTER_X -ChatInputBoxY=SCREEN_CENTER_Y+112 -ChatInputBoxOnCommand=bounceend,0.5;diffusealpha,1 -ChatInputBoxOffCommand=bouncebegin,0.5;zoomy,0 -ChatInputBoxWidth=SCREEN_CENTER_X*0.9 -ChatInputBoxHeight=30 -#--# -ChatInputX=20 -ChatInputY=380 -ChatTextInputWidth=SCREEN_CENTER_X*1.8 -ChatTextInputHeight=30 -ChatInputOnCommand=zoom,0.5;halign,0;valign,0 -ChatInputOffCommand= -#====# -ChatOutputBoxX=20 -ChatOutputBoxY=400 -ChatOutputBoxOnCommand=visible,true;diffusealpha,1;diffuse,color("#FFFFFF") -ChatOutputBoxOffCommand= -ChatOutputBoxWidth=300 -ChatOutputBoxHeight=SCREEN_CENTER_Y*0.875 -#--# -ChatOutputX=20 -ChatOutputY=200 -ChatTextOutputWidth=SCREEN_CENTER_X*1.8 -ChatOutputLines=10 -ChatOutputOnCommand=zoom,0.5;halign,0;valign,0 -ChatOutputOffCommand= - -UsersX=20 -UsersY=SCREEN_BOTTOM-80 -UserSpacingX=64 -UserSpacingY=10 -UserLine2Y=10 -UsersOnCommand=draworder,2;zoom,0.4 -UsersOffCommand=linear,0.5;zoom,0 - -ShowBPMDisplay=false - -ShowBPMLabel=false - [ScreenNetSelectMusic] MusicWheelType="OnlineMusicWheel" -PlayerOptionsScreen="ScreenNestyPlayerOptions" MusicWheelX=SCREEN_WIDTH-(capWideScale(get43size(350),350)) MusicWheelY=SCREEN_CENTER_Y-2 MusicWheelOnCommand=x,SCREEN_WIDTH*2;smooth,0.3;x,SCREEN_WIDTH-(capWideScale(get43size(350),350)); MusicWheelOffCommand=smooth,0.3;x,SCREEN_WIDTH*2; ModIconsP1OnCommand=visible,false -ModIconsP2OnCommand=visible,false #i have no idea why visible,false doesn't work for this. StepsDisplayP1OnCommand=visible,false;diffusealpha,0 -StepsDisplayP2OnCommand=visible,false;diffusealpha,0 ShowBPMDisplay=true BPMDisplayX=(capWideScale(get43size(384),384))-5 @@ -752,6 +728,9 @@ RoomWheelOffCommand=smooth,0.3;x,SCREEN_WIDTH*2; RoomInfoDisplayX=SCREEN_CENTER_X-160 RoomInfoDisplayY=SCREEN_CENTER_Y +ShowBPMDisplay=false +ShowBPMLabel=false + [RoomWheel] RoomWheelItemStartOnCommand= RoomWheelItemFinishOnCommand=