diff --git a/BGAnimations/ScreenColorEdit overlay.lua b/BGAnimations/ScreenColorEdit overlay.lua index 16270309..af8c0886 100644 --- a/BGAnimations/ScreenColorEdit overlay.lua +++ b/BGAnimations/ScreenColorEdit overlay.lua @@ -1,157 +1,701 @@ -local level = 0 -local cursor = 0 -local count = 0 - local selected = getTableKeys() 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) + +local translated_info = { + Description = THEME:GetString("ScreenColorEdit", "Description"), + AboutToSave = THEME:GetString("ScreenColorEdit", "AboutToSave"), + Hexadecimal = THEME:GetString("ScreenColorEdit", "Hexadecimal"), + RGBA = THEME:GetString("ScreenColorEdit", "RedGreenBlueAlpha"), + ManualEntry = THEME:GetString("ScreenColorEdit", "ManualEntry"), + Alpha = THEME:GetString("ScreenColorEdit", "Alpha"), + Saturation = THEME:GetString("ScreenColorEdit", "Saturation"), + DefaultDescription = THEME:GetString("ScreenColorEdit", "DefaultDescription") +} + +local colorBoxHeight = GetScreenAspectRatio() == 1 and 175 or 250 +local saturationSliderWidth = 25 +local genericSpacing = 15 +local saturationOverlay = nil +local saturationSliderPos = nil +local colorPickPosition = nil +local colorPreview = nil +local aboutToSave = false + +local satNum = 0 -- saturation percent +local hueNum = 0 -- degrees 0-360 exclusive +local valNum = 0 -- brightness percent +local alphaNum = 1 -- alpha percent +local currentColor = color("1,1,1") +local hexEntryString = "#" +local textCursorPos = 2 + +local function colorToHSV(color) + local r = color[1] + local g = color[2] + local b = color[3] + local cmax = math.max(r, g, b) + local cmin = math.min(r, g, b) + local dc = cmax - cmin -- delta c + local h = 0 + if dc == 0 then + h = 0 + elseif cmax == r then + h = 60 * (((g-b)/dc) % 6) + elseif cmax == g then + h = 60 * (((b-r)/dc) + 2) + elseif cmax == b then + h = 60 * (((r-g)/dc) + 4) + end + local s = (cmax == 0 and 0 or dc / cmax) + local v = cmax + + local alpha = (color[4] and color[4] or 1) + + return h, 1-s, 1-v, alpha end +local function applyHSV() + local newColor = HSV(hueNum, 1 - satNum, 1 - valNum) + newColor[4] = alphaNum + currentColor = newColor + colorPickPosition:xy(saturationSliderWidth + (colorBoxHeight * hueNum/360), colorBoxHeight * valNum) + saturationOverlay:diffusealpha(satNum) + saturationSliderPos:y(colorBoxHeight * satNum) + alphaSliderPos:y(colorBoxHeight * (1-alphaNum)) + textCursorPos = 9 + hexEntryString = "#" .. ColorToHex(currentColor) + MESSAGEMAN:Broadcast("ClickedNewColor") +end -local function scroller(index) - count = count+1 - local number = tonumber(colorTable[index],16) - local t = Def.ActorFrame{} +-- set up the initial current color stuff +hueNum, satNum, valNum, alphaNum = colorToHSV(color(themeColor)) - t[#t+1] = LoadFont("Common Normal") .. { - InitCommand=function(self) - self:xy(SCREEN_CENTER_X-60+index*20,SCREEN_CENTER_Y):zoom(0.8) - end, - OnCommand=function(self) - self:settext(string.format("%01X",number or 0)) - if index == cursor then - self:diffuse(color("#FFFFFF")) +local function updateSaturation(percent) + if percent < 0 then percent = 0 elseif percent > 1 then percent = 1 end + + satNum = percent + applyHSV() +end + +local function updateAlpha(percent) + if percent < 0 then percent = 0 elseif percent > 1 then percent = 1 end + + alphaNum = 1 - percent + applyHSV() +end + +local function updateColor(percentX, percentY) + if percentY < 0 then percentY = 0 elseif percentY > 1 then percentY = 1 end + if percentX < 0 then percentX = 0 elseif percentX > 1 then percentX = 1 end + + hueNum = 360 * percentX + valNum = percentY + applyHSV() +end + +local function getRotationZ(self) + local parent = self:GetParent() + if parent == nil then + return self:GetRotationZ() + else + return self:GetRotationZ() + getRotationZ(parent) + end +end + +-- find the x position for a char in text relative to text left edge +local function getXPositionInText(self, index) + local overallWidth = self:GetZoomedWidth() + local tlChar1 = self:getGlyphRect(1) -- top left vertex of first char in text + local tlCharIndex = self:getGlyphRect(index) -- top left of char at text + -- the [1] index is the x coordinate of the vertex + + local theX = tlCharIndex[1] - tlChar1[1] + + return theX * self:GetZoom() +end + +local function getWidthOfChar(self, index) + local tl, bl, tr, br = self:getGlyphRect(index) + local glyphWidth = tr[1] - bl[1] + + return glyphWidth / (self:GetZoom() * 10) -- im not really sure why this works +end + +local function cursorCanMove(speed) + + local maxTextSize = (#hexEntryString == 9 and 9 or #hexEntryString + 1) + + local tmpCursor = textCursorPos + speed + if tmpCursor > maxTextSize or tmpCursor < 2 then + return 0 + end + + return speed +end + +local function localMousePos(self, mx, my) + local rz = math.rad(-getRotationZ(self)) + local x = mx - self:GetTrueX() + local y = my - self:GetTrueY() + return x * math.cos(rz) - y * math.sin(rz), x * math.sin(rz) + y * math.cos(rz) +end + +local function colorToRGBNums(c) + local r = c[1] + local g = c[2] + local b = c[3] + local a = HasAlpha(c) + + local rX = scale(r, 0, 1, 0, 255) + local gX = scale(g, 0, 1, 0, 255) + local bX = scale(b, 0, 1, 0, 255) + local aX = scale(a, 0, 1, 0, 255) + + return rX, gX, bX, aX +end + +local function handleHexEntry(character) + character = character:upper() + + if #hexEntryString <= 9 then -- #23 45 67 89 format + if #hexEntryString == 9 and textCursorPos == 9 then + hexEntryString = hexEntryString:sub(1,-2) .. character + else + if textCursorPos == #hexEntryString + 1 then + hexEntryString = hexEntryString .. character else - self:diffuse(color("#666666")) + local left = hexEntryString:sub(1,textCursorPos-1) + local right = hexEntryString:sub(textCursorPos+1) + hexEntryString = left .. character .. right end - end, - CodeMessageCommand=function(self,params) - if params.Name == "ColorUp" then - if index == cursor then - number = (number + 1)%16 - self:settext(string.format("%01X",number or 0)) - colorTable[index] = string.format("%01X",number or 0) - end - end - if params.Name == "ColorDown" then - if index == cursor then - number = (number - 1)%16 - self:settext(string.format("%01X",number or 0)) - colorTable[index] = string.format("%01X",number or 0) - end + textCursorPos = textCursorPos + 1 + end + end + if textCursorPos > 9 then textCursorPos = 9 end + + aboutToSave = false + MESSAGEMAN:Broadcast("UpdateStringDisplay") +end + +local function handleTextUpdate() + local hxl = #hexEntryString - 1 + local finalcolor = color("1,1,1,1") + + if hxl == 3 or hxl == 4 or hxl == 5 then -- color 3/4/5 hex + finalcolor[1] = tonumber("0x"..hexEntryString:sub(2,2)) / 15 + finalcolor[2] = tonumber("0x"..hexEntryString:sub(3,3)) / 15 + finalcolor[3] = tonumber("0x"..hexEntryString:sub(4,4)) / 15 + if hxl == 4 then finalcolor[4] = tonumber("0x"..hexEntryString:sub(5,5)) / 15 end + if hxl == 5 then finalcolor[4] = tonumber("0x"..hexEntryString:sub(5,6)) / 255 end + elseif hxl == 6 or hxl == 7 or hxl == 8 then -- color 6/7/8 hex + finalcolor[1] = tonumber("0x"..hexEntryString:sub(2,3)) / 255 + finalcolor[2] = tonumber("0x"..hexEntryString:sub(4,5)) / 255 + finalcolor[3] = tonumber("0x"..hexEntryString:sub(6,7)) / 255 + if hxl == 7 then finalcolor[4] = tonumber("0x"..hexEntryString:sub(7,7)) / 15 end + if hxl == 8 then finalcolor[4] = tonumber("0x"..hexEntryString:sub(8,9)) / 255 end + else + return + end + + local r = finalcolor[1] -- [0,1] + local g = finalcolor[2] + local b = finalcolor[3] + local cmax = math.max(r, g, b) + local cmin = math.min(r, g, b) + local dc = cmax - cmin -- delta c + local h = 0 + if dc == 0 then + h = 0 + elseif cmax == r then + h = 60 * (((g-b)/dc) % 6) + elseif cmax == g then + h = 60 * (((b-r)/dc) + 2) + elseif cmax == b then + h = 60 * (((r-g)/dc) + 4) + end + local s = (cmax == 0 and 0 or dc / cmax) + local v = cmax + + hueNum, satNum, valNum, alphaNum = colorToHSV(finalcolor) + + aboutToSave = true + applyHSV() +end + +local function inputeater(event) + if event.type == "InputEventType_FirstPress" then + if event.DeviceInput.button == "DeviceButton_left mouse button" then + MESSAGEMAN:Broadcast("MouseLeftClick") + elseif event.char and event.char:match('[%x]') then -- match all hex + handleHexEntry(event.char) + elseif event.DeviceInput.button == "DeviceButton_delete" then + if INPUTFILTER:IsControlPressed() then + local default = getDefaultColorForCurColor() + hueNum, satNum, valNum, alphaNum = colorToHSV(color(default)) + aboutToSave = false + applyHSV() + elseif INPUTFILTER:IsBeingPressed("right alt") or INPUTFILTER:IsBeingPressed("left alt") then + hueNum, satNum, valNum, alphaNum = colorToHSV(color(themeColor)) + aboutToSave = false + applyHSV() + else + hexEntryString = "#" + textCursorPos = 2 + aboutToSave = false end - if params.Name == "ColorLeft" then - if index == cursor then - self:diffuse(color("#FFFFFF")) + MESSAGEMAN:Broadcast("UpdateStringDisplay") + elseif event.DeviceInput.button == "DeviceButton_backspace" then + if #hexEntryString > 1 then + if textCursorPos - 1 == #hexEntryString then + hexEntryString = hexEntryString:sub(1, -2) else - self:diffuse(color("#666666")) + local left = hexEntryString:sub(1,textCursorPos-1) + local right = hexEntryString:sub(textCursorPos+1) + hexEntryString = left .. "0" .. right end + textCursorPos = textCursorPos + cursorCanMove(-1) + aboutToSave = false + MESSAGEMAN:Broadcast("UpdateStringDisplay") end - if params.Name == "ColorRight" then - if index == cursor then - self:diffuse(color("#FFFFFF")) - else - self:diffuse(color("#666666")) - end + elseif event.button == "Left" or event.button == "MenuLeft" then + local before = textCursorPos + textCursorPos = textCursorPos + cursorCanMove(-1) + if before ~= textCursorPos then + MESSAGEMAN:Broadcast("UpdateStringDisplay") end - if params.Name == "ColorStart" then - if index == cursor then - self:diffuse(color("#FFFFFF")) - else - self:diffuse(color("#666666")) - end + elseif event.button == "Right" or event.button == "MenuRight" then + local before = textCursorPos + textCursorPos = textCursorPos + cursorCanMove(1) + if before ~= textCursorPos then + MESSAGEMAN:Broadcast("UpdateStringDisplay") end - end - } + elseif event.button == "Up" or event.button == "MenuUp" then + if textCursorPos <= #hexEntryString then + local numInIndex = tonumber("0x"..hexEntryString:sub(textCursorPos,textCursorPos)) + numInIndex = numInIndex + 1 + if numInIndex > 15 then numInIndex = 0 end + local theCharacter = ("%X"):format(numInIndex) - return t + local left = hexEntryString:sub(1,textCursorPos-1) + local right = hexEntryString:sub(textCursorPos+1) + hexEntryString = left .. theCharacter .. right + aboutToSave = false + MESSAGEMAN:Broadcast("UpdateStringDisplay") + end + elseif event.button == "Down" or event.button == "MenuDown" then + if textCursorPos <= #hexEntryString then + local numInIndex = tonumber("0x"..hexEntryString:sub(textCursorPos,textCursorPos)) + numInIndex = numInIndex - 1 + if numInIndex < 0 then numInIndex = 15 end + local theCharacter = ("%X"):format(numInIndex) + local left = hexEntryString:sub(1,textCursorPos-1) + local right = hexEntryString:sub(textCursorPos+1) + hexEntryString = left .. theCharacter .. right + aboutToSave = false + MESSAGEMAN:Broadcast("UpdateStringDisplay") + end + end + end end -local t = Def.ActorFrame{ - CodeMessageCommand=function(self,params) +local t = Def.ActorFrame { + OnCommand = function(self) + SCREENMAN:GetTopScreen():AddInputCallback(inputeater) + applyHSV() + end, + CodeMessageCommand = function(self, params) if params.Name == "ColorCancel" then SCREENMAN:GetTopScreen():Cancel() end if params.Name == "ColorStart" then - if cursor < 6 then - cursor = ((cursor)%(count))+1 - else - colorConfig:get_data()[selected[1]][selected[2]] = "#"..table.concat(colorTable) + if aboutToSave then + colorConfig:get_data()[selected[1]][selected[2]] = "#" .. ColorToHex(currentColor) colorConfig:set_dirty() colorConfig:save() - MESSAGEMAN:Broadcast("RowChanged",{level = 1}) + MESSAGEMAN:Broadcast("RowChanged", {level=1}) THEME:ReloadMetrics() - SCREENMAN:SystemMessage(string.format("Color %s %s set to #%s",selected[1],selected[2],table.concat(colorTable))) SCREENMAN:GetTopScreen():Cancel() + else + handleTextUpdate() end end - if params.Name == "ColorRight" then - cursor = ((cursor)%(count))+1 - end - if params.Name == "ColorLeft" then - cursor = ((cursor-2)%(count))+1 + end, + Def.Quad { + Name = "MainBG", + InitCommand = function(self) + self:xy(0, 0):halign(0):valign(0):zoomto(SCREEN_WIDTH, SCREEN_HEIGHT):diffuse(color("#000000")) + self:diffusealpha(0.9) end - end + } } +t[#t+1] = Def.ActorFrame { + Name = "ColorPickEquipment", + InitCommand = function(self) + self:xy(SCREEN_WIDTH / 12, SCREEN_HEIGHT / 8) + 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 -} + Def.Sprite { + Name = "HSVImage", + Texture = THEME:GetPathG("", "color_hsv"), + InitCommand = function(self) + self:zoomto(colorBoxHeight, colorBoxHeight) + self:x(saturationSliderWidth) + self:valign(0):halign(0) + end, + MouseLeftClickMessageCommand = function(self) + if isOver(self) then + local y = INPUTFILTER:GetMouseY() + local x = INPUTFILTER:GetMouseX() + local relX, relY = localMousePos(self, x, y) + aboutToSave = true + updateColor(relX / colorBoxHeight, relY / colorBoxHeight) + end + end + }, + Def.Sprite { + Name = "SaturationOverlay", + Texture = THEME:GetPathG("", "color_sat_overlay"), + InitCommand = function(self) + self:zoomto(colorBoxHeight, colorBoxHeight) + self:x(saturationSliderWidth) + self:diffusealpha(0.0) + self:valign(0):halign(0) + saturationOverlay = self + end, + }, + Def.Quad { + Name = "SaturationSlider", + InitCommand = function(self) + self:zoomto(saturationSliderWidth, colorBoxHeight) + self:valign(0):halign(0) + self:diffuse(color(".7,.7,.7")) + end, + MouseLeftClickMessageCommand = function(self) + if isOver(self) then + local y = INPUTFILTER:GetMouseY() + local x = INPUTFILTER:GetMouseX() + local relX, relY = localMousePos(self, x, y) + aboutToSave = true + updateSaturation(relY / colorBoxHeight) + end + end + }, + Def.Quad { + Name = "SaturationSliderPos", + InitCommand = function(self) + self:diffuse(getMainColor("positive")) + self:zoomto(saturationSliderWidth, 2) + self:xy(0,0) + self:valign(0):halign(0) + saturationSliderPos = self + end, + }, -t[#t+1] = LoadActor("_frame") -t[#t+1] = LoadActor("_mouse", "ScreenColorEdit") + Def.Quad { + Name = "AlphaSlider", + InitCommand = function(self) + self:zoomto(saturationSliderWidth, colorBoxHeight) + self:valign(0):halign(1) + self:diffuse(color(".7,.7,.7")) + end, + MouseLeftClickMessageCommand = function(self) + if isOver(self) then + local y = INPUTFILTER:GetMouseY() + local x = INPUTFILTER:GetMouseX() + local relX, relY = localMousePos(self, x, y) + aboutToSave = true + updateAlpha(relY / colorBoxHeight) + end + end + }, + Def.Quad { + Name = "AlphaSliderPos", + InitCommand = function(self) + self:diffuse(getMainColor("positive")) + self:zoomto(saturationSliderWidth, 2) + self:xy(0,0) + self:valign(0):halign(1) + alphaSliderPos = self + end, + }, + Def.Quad { + Name = "SliderDivider", + InitCommand = function(self) + self:valign(0) + self:y(-15) + self:diffuse(getMainColor("highlight")) + self:zoomto(2, colorBoxHeight + 15) + end + }, -t[#t+1] = Def.Quad{ - InitCommand=function(self) - self:xy(SCREEN_CENTER_X,SCREEN_CENTER_Y+40):zoomto(200,30) - end, - OnCommand=function(self) - self:diffuse(color(themeColor)) - end, - CodeMessageCommand=function(self,params) - if params.Name == "ColorUp" then - self:queuecommand("SetColor") + Def.Sprite { + Name = "ColorPickPosition", + Texture = THEME:GetPathG("", "_thick circle"), + InitCommand = function(self) + self:diffuse(color("1,1,1,.8")) + self:zoomto(7,7) + self:x(saturationSliderWidth) + colorPickPosition = self + end + }, + Def.Quad { + Name = "PickedColorPreview", + InitCommand = function(self) + self:zoomto(colorBoxHeight/4, colorBoxHeight/4) + self:x(colorBoxHeight + saturationSliderWidth) + self:valign(0):halign(0) + colorPreview = self + end, + ClickedNewColorMessageCommand = function(self) + self:diffuse(currentColor) + end + }, + + LoadFont("Common Large") .. { + InitCommand = function(self) + self:valign(1) + self:xy(saturationSliderWidth/2, -3) + self:settext(translated_info["Saturation"]) + self:zoom(0.15) + end, + MouseLeftClickMessageCommand = function(self) + if isOver(self) then + updateSaturation(0) + end end - if params.Name == "ColorDown" then - self:queuecommand("SetColor") + }, + LoadFont("Common Large") .. { + InitCommand = function(self) + self:valign(1) + self:xy(-saturationSliderWidth/2, -3) + self:settext(translated_info["Alpha"]) + self:zoom(0.15) + end, + MouseLeftClickMessageCommand = function(self) + if isOver(self) then + updateAlpha(0) + end end + }, +} + +t[#t+1] = Def.ActorFrame { + Name = "ManualEntryArea", + InitCommand = function(self) + self:xy(SCREEN_WIDTH / 12 + saturationSliderWidth + 5 * colorBoxHeight / 4 + 10, SCREEN_HEIGHT / 8) end, - SetColorCommand=function(self) - self:diffuse(color("#"..table.concat(colorTable))) - end + + LoadFont("Common Large") .. { + InitCommand = function(self) + self:halign(0):valign(0) + self:zoom(0.4) + self:settext(translated_info["ManualEntry"]) + end + }, + LoadFont("Common Large") .. { + Name = "Explanation", + InitCommand = function(self) + self:y(genericSpacing + 5) + self:halign(0):valign(0) + self:zoom(0.25) + self:maxwidth((SCREEN_WIDTH - (SCREEN_WIDTH / 12 + saturationSliderWidth + 5 * colorBoxHeight / 4) - 25) / 0.25) + self:settext(translated_info["Description"]) + end + }, + LoadFont("Common Large") .. { + Name = "InputText", + InitCommand = function(self) + self:y(genericSpacing * 5) + self:halign(0):valign(0) + self:zoom(0.4) + self:settext("#") + end, + UpdateStringDisplayMessageCommand = function(self) + self:settext(hexEntryString) + self:GetParent():GetChild("CursorPosition"):playcommand("UpdateCursorDisplay") + end, + ClickedNewColorMessageCommand = function(self) + self:playcommand("UpdateStringDisplay") + end + }, + Def.Quad { + Name = "CursorPosition", + InitCommand = function(self) + self:x(11) + self:halign(0):valign(0) + self:zoomto(10,2) + self:y(20 + genericSpacing * 5) + end, + UpdateCursorDisplayCommand = function(self) + local pos = 11 + local txt = self:GetParent():GetChild("InputText") + if textCursorPos ~= #hexEntryString + 1 then -- if the cursor is under an actual char + local glyphWidth = getWidthOfChar(txt, textCursorPos) - 1 + self:zoomto(glyphWidth, 2) + pos = getXPositionInText(txt, textCursorPos) + else + pos = getXPositionInText(txt, textCursorPos-1) + getWidthOfChar(txt, textCursorPos-1) + end + self:finishtweening() + self:linear(0.05) + self:x(pos) + end + }, + LoadFont("Common Large") .. { + Name = "SavingIndicator", + InitCommand = function(self) + self:y(genericSpacing * 7) + self:settext(translated_info["AboutToSave"]) + self:valign(0):halign(0) + self:zoom(0.5) + self:visible(false) + end, + ClickedNewColorMessageCommand = function(self) + self:visible(aboutToSave) + end, + UpdateStringDisplayMessageCommand = function(self) + self:visible(aboutToSave) + end + + }, + LoadFont("Common Large") .. { + Name = "SelectedTypeIndicator", + InitCommand = function(self) + self:y(genericSpacing * 10) + self:valign(0):halign(0) + self:settextf("%s - %s", THEME:GetString("ScreenColorChange", selected[1]), THEME:GetString("ScreenColorChange", selected[2])) + self:zoom(0.4) + self:maxwidth((SCREEN_WIDTH - (SCREEN_WIDTH / 12 + saturationSliderWidth + 5 * colorBoxHeight / 4) - 25) / 0.4) + end + } } -t[#t+1] = LoadFont("Common Normal") .. { - InitCommand=function(self) - self:xy(SCREEN_CENTER_X-60,SCREEN_CENTER_Y):zoom(0.8) +t[#t+1] = Def.ActorFrame { + Name = "ColorPickInformation", + InitCommand = function(self) + self:xy(SCREEN_WIDTH / 12, SCREEN_HEIGHT / 8 + colorBoxHeight + genericSpacing) end, - OnCommand=function(self) - self:settext("#") - self:diffuse(color("#666666")) - end + + LoadFont("Common Large") .. { + InitCommand = function(self) + self:valign(0):halign(0):zoom(0.4) + self:settext("Current Color") + end, + }, + LoadFont("Common Large") .. { + Name = "RGBInfo", + InitCommand = function(self) + self:y(20) + self:valign(0):halign(0):zoom(0.4) + self:settextf("%s:", translated_info["RGBA"]) + end + }, + LoadFont("Common Large") .. { + Name = "HexInfo", + InitCommand = function(self) + self:y(40) + self:valign(0):halign(0):zoom(0.4) + self:settextf("%s:", translated_info["Hexadecimal"]) + end + }, + LoadFont("Common Large") .. { + Name = "SelectedRGB", + InitCommand = function(self) + self:y(20) + self:x(colorBoxHeight) + self:valign(0):halign(1):zoom(0.4) + self:maxwidth((colorBoxHeight / 1.5) / 0.4) + end, + ClickedNewColorMessageCommand = function(self) + local r,g,b,a = colorToRGBNums(currentColor) + self:settextf("%.2f, %.2f, %.2f, %.2f", r,g,b,a) + end + }, + LoadFont("Common Large") .. { + Name = "SelectedHex", + InitCommand = function(self) + self:x(colorBoxHeight) + self:y(40) + self:valign(0):halign(1):zoom(0.4) + self:maxwidth((colorBoxHeight / 1.5) / 0.4) + end, + ClickedNewColorMessageCommand = function(self) + local clr = ColorToHex(currentColor) + self:settext(clr) + end + } } -t[#t+1] = LoadFont("Common Normal") .. { - InitCommand=function(self) - self:xy(SCREEN_CENTER_X,SCREEN_CENTER_Y+100):zoom(0.4) +t[#t+1] = Def.ActorFrame { + Name = "OldInfo", + InitCommand = function(self) + self:xy(SCREEN_WIDTH / 12 + saturationSliderWidth + 5 * colorBoxHeight / 4 + 10, SCREEN_HEIGHT / 8 + colorBoxHeight + genericSpacing) end, - OnCommand=function(self) - self:settextf("%s \"%s - %s\".\n\n%s",THEME:GetString("ScreenColorEdit","Description1"),THEME:GetString("ScreenColorChange", selected[1]),THEME:GetString("ScreenColorChange", selected[2]),THEME:GetString("ScreenColorEdit","Description2")) - self:diffuse(color("#FFFFFF")) - end + + LoadFont("Common Large") .. { + InitCommand = function(self) + self:settext("Saved Color") + self:halign(0):valign(0) + self:zoom(0.4) + end + }, + LoadFont("Common Large") .. { + Name = "SelectedRGB", + InitCommand = function(self) + self:y(20) + self:valign(0):halign(0):zoom(0.4) + local svd = color(themeColor) + local r,g,b,a = colorToRGBNums(svd) + self:settextf("%.2f, %.2f, %.2f, %.2f", r,g,b,a) + self:maxwidth((colorBoxHeight / 1.5) / 0.4) + end, + UpdateSavedColorMessageCommand = function(self) + local svd = color(themeColor) + local r,g,b,a = colorToRGBNums(svd) + self:settextf("%.2f, %.2f, %.2f, %.2f", r,g,b,a) + end + }, + LoadFont("Common Large") .. { + Name = "SelectedHex", + InitCommand = function(self) + self:y(40) + self:valign(0):halign(0):zoom(0.4) + self:settext(themeColor:upper()) + self:maxwidth((colorBoxHeight / 1.5) / 0.4) + end, + UpdateSavedColorMessageCommand = function(self) + self:settext(themeColor:upper()) + end + }, + Def.Quad { + Name = "SavedPreview", + InitCommand = function(self) + self:x(colorBoxHeight / 1.5 + 5) + self:halign(0):valign(0) + self:zoomto(colorBoxHeight/4, colorBoxHeight/4) + self:diffuse(color(themeColor)) + end, + UpdateSavedColorMessageCommand = function(self) + self:diffuse(color(themeColor)) + end + }, + LoadFont("Common Large") .. { + InitCommand = function(self) + self:y(65) + self:valign(0):halign(0) + self:zoom(0.25) + self:maxwidth((SCREEN_WIDTH - colorBoxHeight * 2 - 15) / 0.25) + self:settext(translated_info["DefaultDescription"]) + end + } } -for i=1,6 do - t[#t+1] = scroller(i) -end +t[#t+1] = LoadActor("_frame") +t[#t+1] = LoadActor("_mouse", "ScreenColorEdit") return t \ No newline at end of file diff --git a/BGAnimations/ScreenEvaluation decorations/default.lua b/BGAnimations/ScreenEvaluation decorations/default.lua index 3a7a0859..17f5818b 100644 --- a/BGAnimations/ScreenEvaluation decorations/default.lua +++ b/BGAnimations/ScreenEvaluation decorations/default.lua @@ -10,7 +10,7 @@ local frameY = 150 local frameWidth = SCREEN_CENTER_X-WideScale(get43size(40),40) local frameHeight = 300 local rate = getCurRate() -local judge = GetTimingDifficulty() +local judge = (PREFSMAN:GetPreference("SortBySSRNormPercent") and 4 or GetTimingDifficulty()) local offsetIndex -- Reset preview music starting point since song was finished. @@ -30,6 +30,7 @@ local showScoreboardOnSimple = themeConfig:get_data().global.ShowScoreboardOnSim local offsetY2 = 0 local offsetWidth2 = 0 local offsetHeight2 = 0 +local offsetisLocal local function scroller(event) if event.type == "InputEventType_FirstPress" then @@ -96,7 +97,7 @@ local function oldEvalStuff() rescoredPercentage = getRescoredWifeJudge(dvt, judge, totalHolds - holdsHit, minesHit, totalTaps) end if params.Name == "ResetJudge" then - judge = enabledCustomWindows and 0 or GetTimingDifficulty() + judge = enabledCustomWindows and 0 or (PREFSMAN:GetPreference("SortBySSRNormPercent") and 4 or GetTimingDifficulty()) self:GetParent():playcommand("ResetJudge") elseif params.Name ~= "ToggleHands" then self:GetParent():playcommand("SetJudge", params) @@ -687,10 +688,15 @@ local function oldEvalStuff() self:playcommand("Set") end, SetCommand = function(self) - self:settext(THEME:GetString("ScreenEvaluation","CategoryClearType")) + if PREFSMAN:GetPreference("SortBySSRNormPercent") then + self:settextf("%s (J4)", THEME:GetString("ScreenEvaluation", "CategoryClearType")) + else + self:settext(THEME:GetString("ScreenEvaluation","CategoryClearType")) + end end, SetJudgeCommand = function(self) - self:settextf("%s (J%d)", THEME:GetString("ScreenEvaluation", "CategoryClearType"), GetTimingDifficulty()) + local jdg = (PREFSMAN:GetPreference("SortBySSRNormPercent") and 4 or GetTimingDifficulty()) + self:settextf("%s (J%d)", THEME:GetString("ScreenEvaluation", "CategoryClearType"), jdg) end, ResetJudgeCommand = function(self) self:playcommand("Set") @@ -767,10 +773,15 @@ local function oldEvalStuff() self:playcommand("Set") end, SetCommand = function(self) - self:settextf("%s - %s",THEME:GetString("ScreenEvaluation","CategoryScore"),getScoreTypeText(1)) + if PREFSMAN:GetPreference("SortBySSRNormPercent") then + self:settextf("%s - %s J4", THEME:GetString("ScreenEvaluation","CategoryScore"), getScoreTypeText(1)) + else + 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()) + local jdg = (PREFSMAN:GetPreference("SortBySSRNormPercent") and 4 or GetTimingDifficulty()) + self:settextf("%s - %s J%d", THEME:GetString("ScreenEvaluation", "CategoryScore"), getScoreTypeText(1), jdg) end, ResetJudgeCommand = function(self) self:playcommand("Set") @@ -1280,7 +1291,6 @@ local function oldEvalStuff() local lbActor local offsetScoreID - local offsetisLocal local currentCountry = "Global" local scoresPerPage = 5 local maxPages = math.ceil(#hsTable/scoresPerPage) diff --git a/BGAnimations/ScreenSelectMusic overlay/currentsort.lua b/BGAnimations/ScreenSelectMusic overlay/currentsort.lua index d53f41cf..963dad00 100644 --- a/BGAnimations/ScreenSelectMusic overlay/currentsort.lua +++ b/BGAnimations/ScreenSelectMusic overlay/currentsort.lua @@ -14,6 +14,7 @@ local wheel local song local released = false local goneOff = false +local instantSearch = themeConfig:get_data().global.InstantSearch local sortTable = { SortOrder_Preferred = 'Preferred', @@ -79,6 +80,9 @@ local function searchInput(event) MESSAGEMAN:Broadcast("EndSearch") elseif event.button == "Start" then + if not instantSearch then + wheel:SongSearch(searchstring) + end MESSAGEMAN:Broadcast("EndSearch") elseif event.button == "MenuLeft" then @@ -115,7 +119,11 @@ local function searchInput(event) end end if lastsearchstring ~= searchstring then - wheel:SongSearch(searchstring) + if instantSearch then + wheel:SongSearch(searchstring) + else + sortText:playcommand("SetSortOrder") + end lastsearchstring = searchstring GHETTOGAMESTATE:setMusicSearch(searchstring) end @@ -207,6 +215,7 @@ t[#t+1] = LoadFont("Common Normal") .. { self:zoom(0.45) self:diffuse(color(colorConfig:get_data().main.headerFrameText)) self:maxwidth((frameWidth-40)/0.45) + sortText = self end, SortOrderChangedMessageCommand = function(self) self:queuecommand("SetSortOrder") diff --git a/BGAnimations/ScreenSelectMusic overlay/net/currentsort.lua b/BGAnimations/ScreenSelectMusic overlay/net/currentsort.lua index e0cca5bf..062bfbf9 100644 --- a/BGAnimations/ScreenSelectMusic overlay/net/currentsort.lua +++ b/BGAnimations/ScreenSelectMusic overlay/net/currentsort.lua @@ -14,6 +14,7 @@ local wheel local song local released = false local goneOff = false +local instantSearch = themeConfig:get_data().global.InstantSearch local sortTable = { SortOrder_Preferred = 'Preferred', @@ -79,6 +80,9 @@ local function searchInput(event) MESSAGEMAN:Broadcast("EndSearch") elseif event.button == "Start" then + if not instantSearch then + wheel:SongSearch(searchstring) + end MESSAGEMAN:Broadcast("EndSearch") elseif event.button == "MenuLeft" then @@ -115,7 +119,11 @@ local function searchInput(event) end end if lastsearchstring ~= searchstring then - wheel:SongSearch(searchstring) + if instantSearch then + wheel:SongSearch(searchstring) + else + sortText:playcommand("SetSortOrder") + end lastsearchstring = searchstring GHETTOGAMESTATE:setMusicSearch(searchstring) end @@ -207,6 +215,7 @@ t[#t+1] = LoadFont("Common Normal") .. { self:zoom(0.45) self:diffuse(color(colorConfig:get_data().main.headerFrameText)) self:maxwidth((frameWidth-40)/0.45) + sortText = self end, SortOrderChangedMessageCommand = function(self) self:queuecommand("SetSortOrder") diff --git a/Graphics/OffsetGraph.lua b/Graphics/OffsetGraph.lua index a59e5125..8b0647c2 100644 --- a/Graphics/OffsetGraph.lua +++ b/Graphics/OffsetGraph.lua @@ -7,7 +7,7 @@ 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 judge = (PREFSMAN:GetPreference("SortBySSRNormPercent") and 4 or GetTimingDifficulty()) local tso = tst[judge] local enabledCustomWindows = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomEvaluationWindowTimings @@ -95,8 +95,8 @@ local t = Def.ActorFrame{ end end if params.Name == "ResetJudge" then - judge = enabledCustomWindows and 0 or GetTimingDifficulty() - tso = tst[GetTimingDifficulty()] + judge = enabledCustomWindows and 0 or (PREFSMAN:GetPreference("SortBySSRNormPercent") and 4 or GetTimingDifficulty()) + tso = tst[(PREFSMAN:GetPreference("SortBySSRNormPercent") and 4 or GetTimingDifficulty())] end if params.Name ~= "ResetJudge" and params.Name ~= "PrevJudge" and params.Name ~= "NextJudge" and params.Name ~= "ToggleHands" then return end maxOffset = (enabledCustomWindows and judge ~= 0) and customWindow.judgeWindows.boo or math.max(180, 180 * tso) diff --git a/Graphics/_thick circle (doubleres).png b/Graphics/_thick circle (doubleres).png new file mode 100644 index 00000000..d55a3a71 Binary files /dev/null and b/Graphics/_thick circle (doubleres).png differ diff --git a/Graphics/color_hsv.png b/Graphics/color_hsv.png new file mode 100644 index 00000000..8bd743d3 Binary files /dev/null and b/Graphics/color_hsv.png differ diff --git a/Graphics/color_sat_overlay.png b/Graphics/color_sat_overlay.png new file mode 100644 index 00000000..6b30e2ad Binary files /dev/null and b/Graphics/color_sat_overlay.png differ diff --git a/Languages/en.ini b/Languages/en.ini index ac6ce020..ad60cca6 100644 --- a/Languages/en.ini +++ b/Languages/en.ini @@ -137,6 +137,7 @@ TargetTrackerMode = Target Tracker Mode Leaderboard = Gameplay Leaderboard LeaderboardSlots = Leaderboard Slots AnimatedLeaderboard = Leaderboard Animations +InstantSearch=Instant Search [OptionExplanations] @@ -176,6 +177,7 @@ DisplayMean = Show your current tap mean. 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. +InstantSearch=Turn this on to have the Song Wheel update for every letter you put into the song search. If you lag when searching, turn this off. [OptionTitles] JudgeType=Judge Count @@ -321,25 +323,25 @@ PacemakerCurrent=Pacemaker Current (unused) PacemakerTarget=Pacemaker Target (unused) ScreenFilter=Notefield Filter Color -grade=Grade +grades=Grade Grade_Failed=Failed Grade_None=None -Grade_Tier01=AAAA -Grade_Tier02=AAA -Grade_Tier03=AA -Grade_Tier04=A -Grade_Tier05=B -Grade_Tier06=C -Grade_Tier07=D -Grade_Tier08=Grade_Tier08 -Grade_Tier09=Grade_Tier09 -Grade_Tier10=Grade_Tier10 -Grade_Tier11=Grade_Tier11 -Grade_Tier12=Grade_Tier12 -Grade_Tier13=Grade_Tier13 -Grade_Tier14=Grade_Tier14 -Grade_Tier15=Grade_Tier15 -Grade_Tier16=Grade_Tier16 +Grade_Tier01=AAAAA +Grade_Tier02=AAAA: +Grade_Tier03=AAAA. +Grade_Tier04=AAAA +Grade_Tier05=AAA: +Grade_Tier06=AAA. +Grade_Tier07=AAA +Grade_Tier08=AA: +Grade_Tier09=AA. +Grade_Tier10=AA +Grade_Tier11=A: +Grade_Tier12=A. +Grade_Tier13=A +Grade_Tier14=B +Grade_Tier15=C +Grade_Tier16=D Grade_Tier17=Grade_Tier17 judgment=Judgments @@ -403,6 +405,15 @@ ultramarathon=Ultramarathon [ScreenColorEdit] HeaderText=Color Config +Description=Press to confirm a typed color. Use to move the cursor\nUse and to reset characters\nPress after confirming or after clicking to save and exit\nPress to exit without saving +AboutToSave=ABOUT TO SAVE +ManualEntry=Manual Entry +Hexadecimal=Hex +RedGreenBlueAlpha=RGBA +Saturation=Sat +Alpha=Alpha +DefaultDescription=Press to select the default color\nPress to undo changes + Description1=This will change the color Description2=Press / to move cursor, / to change value.\nPress to confirm and to exit.\nPlease reload metrics after changing colors as some colors will not update unless you do so. diff --git a/Scripts/00 ThemeInfo.lua b/Scripts/00 ThemeInfo.lua index 1e2b70c9..bb73f013 100644 --- a/Scripts/00 ThemeInfo.lua +++ b/Scripts/00 ThemeInfo.lua @@ -1,9 +1,9 @@ -- theme identification file themeInfo = { - Name = "spawncamping-wallhack (etterna .67.1)", - Version = "2.2.2", -- a.b.c, a for complete overhauls, b for major releases, c for minor additions/bugfix. - Date = "20200108", + Name = "spawncamping-wallhack (etterna .68.1)", + Version = "2.2.3", -- a.b.c, a for complete overhauls, b for major releases, c for minor additions/bugfix. + Date = "20200225", } function getThemeName() diff --git a/Scripts/01 color_config.lua b/Scripts/01 color_config.lua index ac4e00a0..0e844c7f 100644 --- a/Scripts/01 color_config.lua +++ b/Scripts/01 color_config.lua @@ -62,26 +62,26 @@ local defaultConfig = { Freestyle = "#666666", -- gray }, - grade = { - Grade_Tier01 = "#66ccff", -- AAAA - Grade_Tier02 = "#eebb00", -- AAA - Grade_Tier03 = "#66cc66", -- AA - Grade_Tier04 = "#da5757", -- A - Grade_Tier05 = "#5b78bb", -- B - Grade_Tier06 = "#c97bff", -- C - Grade_Tier07 = "#8c6239", -- D - Grade_Tier08 = "#000000", -- ITG PLS - Grade_Tier09 = "#000000", -- ITG PLS - Grade_Tier10 = "#000000", -- ITG PLS - Grade_Tier11 = "#000000", -- ITG PLS - Grade_Tier12 = "#000000", -- ITG PLS - Grade_Tier13 = "#000000", -- ITG PLS - Grade_Tier14 = "#000000", -- ITG PLS - Grade_Tier15 = "#000000", -- ITG PLS - Grade_Tier16 = "#000000", -- ITG PLS - Grade_Tier17 = "#000000", -- ITG PLS - Grade_Failed = "#cdcdcd", -- F - Grade_None = "#666666", -- no play + grades = { + Grade_Tier01 = "#ffffff", -- AAAAA + Grade_Tier02 = "#66ccff", -- AAAA: + Grade_Tier03 = "#66ccff", -- AAAA. + Grade_Tier04 = "#66ccff", -- AAAA + Grade_Tier05 = "#eebb00", -- AAA: + Grade_Tier06 = "#eebb00", -- AAA. + Grade_Tier07 = "#eebb00", -- AAA + Grade_Tier08 = "#66cc66", -- AA: + Grade_Tier09 = "#66cc66", -- AA. + Grade_Tier10 = "#66cc66", -- AA + Grade_Tier11 = "#da5757", -- A: + Grade_Tier12 = "#da5757", -- A. + Grade_Tier13 = "#da5757", -- A + Grade_Tier14 = "#5b78bb", -- B + Grade_Tier15 = "#c97bff", -- C + Grade_Tier16 = "#8c6239", -- D + Grade_Tier17 = "#000000", + Grade_Failed = "#cdcdcd", -- F + Grade_None = "#666666" -- no play }, judgment = { -- Colors of each Judgment types @@ -184,6 +184,10 @@ function setTableKeys(table) curColor = table end +function getDefaultColorForCurColor() + return defaultConfig[curColor[1]][curColor[2]] +end + function getMainColor(type) return color(colorConfig:get_data().main[type]) end @@ -196,8 +200,8 @@ 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']) +function getGradeColor(grade) + return color(colorConfig:get_data().grades[grade]) or color(colorConfig:get_data().grades['Grade_None']) end function getDifficultyColor(diff) @@ -340,7 +344,7 @@ 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"]) + return color(colorConfig:get_data().grades[grade]) or color(colorConfig:get_data().grades["Grade_None"]) end -- Colorized stuff diff --git a/Scripts/01 theme_config.lua b/Scripts/01 theme_config.lua index a63d2a12..11d11cdc 100644 --- a/Scripts/01 theme_config.lua +++ b/Scripts/01 theme_config.lua @@ -21,7 +21,8 @@ local defaultConfig = { EvalScoreboard = true, SimpleEval = true, -- false means use classic eval ShowScoreboardOnSimple = false, - PlayerInfoType = true -- true is full, false is minimal (lifebar only) + PlayerInfoType = true, -- true is full, false is minimal (lifebar only) + InstantSearch = true, -- true = search per press, false = search on enter button }, NPSDisplay = { DynamicWindow = false, -- unused diff --git a/Scripts/02 ThemePrefs.lua b/Scripts/02 ThemePrefs.lua index 1abc0640..b699291b 100644 --- a/Scripts/02 ThemePrefs.lua +++ b/Scripts/02 ThemePrefs.lua @@ -745,6 +745,38 @@ function SimpleEval() return t end +function InstantSearch() + local t = { + Name = "InstantSearch", + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = true, + Choices = {THEME:GetString("OptionNames", "Off"), THEME:GetString("OptionNames", "On")}, + LoadSelections = function(self, list, pn) + local pref = themeConfig:get_data().global.InstantSearch + 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.InstantSearch = value + themeConfig:set_dirty() + themeConfig:save() + end + } + setmetatable(t, t) + return t +end + function ShowScoreboardOnSimple() local t = { Name = "ShowScoreboardOnSimple", diff --git a/Scripts/Scores.lua b/Scripts/Scores.lua index 6eafbaec..8bf8527c 100644 --- a/Scripts/Scores.lua +++ b/Scripts/Scores.lua @@ -1,73 +1,63 @@ WifeTiers = { - Grade_Tier01 = 0.9997, - Grade_Tier02 = 0.9975, - Grade_Tier03 = 0.93, - Grade_Tier04 = 0.8, - Grade_Tier05 = 0.7, - Grade_Tier06 = 0.6, - Grade_Tier07 = 0.0 + Grade_Tier01 = 0.99999, + Grade_Tier02 = 0.9999, + Grade_Tier03 = 0.9998, + Grade_Tier04 = 0.9997, + Grade_Tier05 = 0.9992, + Grade_Tier06 = 0.9985, + Grade_Tier07 = 0.9975, + Grade_Tier08 = 0.99, + Grade_Tier09 = 0.965, + Grade_Tier10 = 0.93, + Grade_Tier11 = 0.9, + Grade_Tier12 = 0.85, + Grade_Tier13 = 0.8, + Grade_Tier14 = 0.7, + Grade_Tier15 = 0.6, + Grade_Tier16 = 0.5, } -WifeTierList = {"Grade_Tier01","Grade_Tier02","Grade_Tier03","Grade_Tier04","Grade_Tier05","Grade_Tier06","Grade_Tier07"} - -function getWifeGradeTier(percent) - percent = percent / 100 - for _,v in pairs(WifeTierList) do - if percent > WifeTiers[v] then - return v - end - end - - return "Grade_Tier07" +WifeTierList = {"Grade_Tier01","Grade_Tier02","Grade_Tier03","Grade_Tier04","Grade_Tier05","Grade_Tier06","Grade_Tier07","Grade_Tier08","Grade_Tier09","Grade_Tier10","Grade_Tier11","Grade_Tier12","Grade_Tier13","Grade_Tier14","Grade_Tier15","Grade_Tier16"} +function isMidGrade(grade) + return grade == "Grade_Tier02" or grade == "Grade_Tier03" or grade == "Grade_Tier05" or grade == "Grade_Tier06" or grade == "Grade_Tier08" or grade == "Grade_Tier09" or grade == "Grade_Tier11" or grade == "Grade_Tier12" end -function getScoresByKey(pn, steps) - local song = GAMESTATE:GetCurrentSong() - local profile - if GAMESTATE:IsPlayerEnabled(pn) then - profile = GetPlayerOrMachineProfile(pn) - - if steps == nil then - steps = GAMESTATE:GetCurrentSteps(pn) - end - - if profile ~= nil and steps ~= nil and song ~= nil then - return SCOREMAN:GetScoresByKey(steps:GetChartKey()) +function gradeFamilyToBetterGrade(grade) + if grade == "Grade_Tier04" then + return "Grade_Tier01" + elseif grade == "Grade_Tier07" then + return "Grade_Tier04" + elseif grade == "Grade_Tier10" then + return "Grade_Tier07" + elseif grade == "Grade_Tier14" then + return "Grade_Tier10" + else + if grade == "Grade_Tier01" then + return grade + else + return string.format("Grade_Tier%02d",(tonumber(grade:sub(-2))-1)) end end - return nil end -function getMaxNotes(pn) - if not GAMESTATE:IsPlayerEnabled(pn) then - return 0 - end - local steps = GAMESTATE:GetCurrentSteps(pn) - if steps ~= nil then - if GAMESTATE:CountNotesSeparately() then - return steps:GetRadarValues(pn):GetValue("RadarCategory_Notes") or 0 +function getWifeGradeTier(percent) + percent = percent / 100 + local midgrades = PREFSMAN:GetPreference("UseMidGrades") + for _,v in pairs(WifeTierList) do + if not midgrades and isMidGrade(v) then + -- not using midgrades, skip the midgrades else - return steps:GetRadarValues(pn):GetValue("RadarCategory_TapsAndHolds") or 0 + if percent > WifeTiers[v] then + return v + end end - else - return 0 end -end -function getMaxHolds(pn) - if not GAMESTATE:IsPlayerEnabled(pn) then - return 0 - end + return "Grade_Tier16" - local steps = GAMESTATE:GetCurrentSteps(pn) - if steps ~= nil then - return (steps:GetRadarValues(pn):GetValue("RadarCategory_Holds") + steps:GetRadarValues(pn):GetValue("RadarCategory_Rolls")) or 0 - else - return 0 - end end --Gets the highest score possible for the scoretype @@ -89,14 +79,20 @@ function getNearbyGrade(pn, wifeScore, grade) local nextGrade local gradeScore = 0 local nextGradeScore = 0 + local midgrades = PREFSMAN:GetPreference("UseMidGrades") if grade == "Grade_Tier01" then return grade, 0 elseif grade == "Grade_Failed" then - return "Grade_Tier07", wifeScore + return "Grade_Tier16", wifeScore elseif grade == "Grade_None" then - return "Grade_Tier07", 0 + return "Grade_Tier16", 0 else - nextGrade = string.format("Grade_Tier%02d",(tonumber(grade:sub(-2))-1)) + if not midgrades then + local grd = getGradeFamilyForMidGrade(grade) + nextGrade = gradeFamilyToBetterGrade(grd) + else + nextGrade = string.format("Grade_Tier%02d",(tonumber(grade:sub(-2))-1)) + end gradeScore = getGradeThreshold(pn,grade) nextGradeScore = getGradeThreshold(pn,nextGrade) @@ -120,42 +116,6 @@ function getScoreGrade(score) end end -function getScoreMaxCombo(score) - if score ~= nil then - return score:GetMaxCombo() - else - return 0 - end -end - -function getScoreDate(score) - if score ~= nil then - return score:GetDate() - else - return "" - end -end - -function getScoreTapNoteScore(score,tns) - if score ~= nil then - return score:GetTapNoteScore(tns) - else - return 0 - end -end - -function getScoreHoldNoteScore(score,tns) - if score ~= nil then - return score:GetHoldNoteScore(tns) - else - return 0 - end -end - -function getScoreMissCount(score) - return getScoreTapNoteScore(score,"TapNoteScore_Miss") + getScoreTapNoteScore(score,"TapNoteScore_W5") + getScoreTapNoteScore(score,"TapNoteScore_W4") -end - -- Do this until the raw wife score is exposed to lua. function getScore(score, steps, percent) if percent == nil then percent = true end @@ -185,19 +145,6 @@ function sortScore(hsTable) return hsTable end --- returns a string corresponding to the rate mod used in the highscore. -function getRate(score) - -- gets the rate mod used in highscore. doesn't work if ratemod has a different name - local mods = score:GetModifiers() - if string.find(mods,"Haste") ~= nil then - return 'Haste' - elseif string.find(mods,"xMusic") == nil then - return '1.0x' - else - return (string.match(mods,"%d+%.%d+xMusic")):sub(1,-6) - end -end - function getCurRate() local mods = GAMESTATE:GetSongOptionsString() if string.find(mods,"Haste") ~= nil then @@ -209,45 +156,6 @@ function getCurRate() end end --- returns the index of the highscore in a given highscore table. -function getHighScoreIndex(hsTable,score) - for k,v in ipairs(hsTable) do - if v:GetDate() == score:GetDate() then - return k - end - end - return 0 -end - --- Returns a table containing tables containing scores for each ratemod used. -function getRateTable(pn, steps) - local o = getScoresByKey(pn, steps) - if not o then return nil end - - for k,v in pairs(o) do - o[k] = o[k]:GetScores() - end - - return o -end - -function getUsedRates(rtTable) - local rates = {} - local initIndex = 1 - if rtTable ~= nil then - for k,v in pairs(rtTable) do - rates[#rates+1] = k - end - table.sort(rates,function(a,b) a=a:gsub("x","") b=b:gsub("x","") return a