Merge branch 'master' into feat/titlescreem-redo
|
@ -10,6 +10,7 @@ Project Starter: GSK Bladez
|
||||||
- Hoshikara
|
- Hoshikara
|
||||||
- GSK Bladez
|
- GSK Bladez
|
||||||
- Local
|
- Local
|
||||||
|
- Kuenaimaku
|
||||||
|
|
||||||
## Graphics
|
## Graphics
|
||||||
- GSK Bladez
|
- GSK Bladez
|
||||||
|
|
|
@ -62,6 +62,12 @@
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"gameplay_showSearchControls": {
|
||||||
|
"label": "Show song select controls when searching",
|
||||||
|
"type": "bool",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
|
||||||
"separator_f": {},
|
"separator_f": {},
|
||||||
"Debug": { "type": "label" },
|
"Debug": { "type": "label" },
|
||||||
|
|
|
@ -131,6 +131,10 @@ ImageFont.draw = function(this, text, x, y, alpha, hFlag, vFlag)
|
||||||
end
|
end
|
||||||
|
|
||||||
function GetDisplayDifficulty(jacketPath, difficulty)
|
function GetDisplayDifficulty(jacketPath, difficulty)
|
||||||
|
if jacketPath == nil then
|
||||||
|
return difficulty
|
||||||
|
end
|
||||||
|
|
||||||
local strippedPath = string.match(jacketPath:lower(), "[/\\][^\\/]+$")
|
local strippedPath = string.match(jacketPath:lower(), "[/\\][^\\/]+$")
|
||||||
if difficulty == 3 and strippedPath then
|
if difficulty == 3 and strippedPath then
|
||||||
if string.find(strippedPath, "inf") ~= nil then
|
if string.find(strippedPath, "inf") ~= nil then
|
||||||
|
|
|
@ -15,6 +15,7 @@ local difficultyLabelTexts = {
|
||||||
"ADV",
|
"ADV",
|
||||||
"EXH",
|
"EXH",
|
||||||
"MXM",
|
"MXM",
|
||||||
|
"INF",
|
||||||
"GRV",
|
"GRV",
|
||||||
"HVN",
|
"HVN",
|
||||||
"VVD"
|
"VVD"
|
||||||
|
@ -29,7 +30,7 @@ function render(deltatime, x, y, scale, diff, level)
|
||||||
|
|
||||||
gfx.BeginPath();
|
gfx.BeginPath();
|
||||||
gfx.ImageRect(0, 0, 140, 31 ,
|
gfx.ImageRect(0, 0, 140, 31 ,
|
||||||
difficultyLabelImages[diff+1] or
|
difficultyLabelImages[diff] or
|
||||||
difficultyLabelImages[4], 1, 0);
|
difficultyLabelImages[4], 1, 0);
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ function render(deltatime, x, y, scale, diff, level)
|
||||||
gfx.FontSize(22)
|
gfx.FontSize(22)
|
||||||
gfx.Scale(1.2,1); -- Make the diff text more W I D E
|
gfx.Scale(1.2,1); -- Make the diff text more W I D E
|
||||||
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE)
|
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE)
|
||||||
gfx.Text(difficultyLabelTexts[diff+1], 18, 17);
|
gfx.Text(difficultyLabelTexts[diff], 18, 17);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,9 @@ end
|
||||||
|
|
||||||
function update_score(newScore)
|
function update_score(newScore)
|
||||||
score = newScore
|
score = newScore
|
||||||
|
if (score == 0) then
|
||||||
|
maxChain = 0;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function update_combo(newCombo)
|
function update_combo(newCombo)
|
||||||
|
|
|
@ -98,7 +98,8 @@ local render = function (deltaTime, bpm, laneSpeed, jacketPath, diff, level, pro
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Draw diff rectangle
|
-- Draw diff rectangle
|
||||||
DiffRectangle.render(deltaTime, 31, y+140, 0.84, diff, level);
|
local adjustedDiff = GetDisplayDifficulty(gameplay.jacketPath, diff)
|
||||||
|
DiffRectangle.render(deltaTime, 31, y+140, 0.84, adjustedDiff, level);
|
||||||
|
|
||||||
gfx.FontSize(30);
|
gfx.FontSize(30);
|
||||||
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE)
|
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE)
|
||||||
|
|
|
@ -2,37 +2,37 @@
|
||||||
local lang = {
|
local lang = {
|
||||||
Challanges = {
|
Challanges = {
|
||||||
--rightside
|
--rightside
|
||||||
ch = "Idk",
|
ch = "Analyze your skill!",
|
||||||
ch1 = "Torture yourself :)",
|
ch1 = "Find out how good you are by taking on challenges!\nIn this mode your ability will pushed to the limits.",
|
||||||
},
|
},
|
||||||
Multiplayer = {
|
Multiplayer = {
|
||||||
--rightside
|
--rightside
|
||||||
mp = "Wait, there's multiplayer???",
|
mp = "Online matchmaking!",
|
||||||
mp2 = "Yes, but nobody is ever online",
|
mp2 = "Play against your friends!\nSupport for up to 8 players.",
|
||||||
},
|
},
|
||||||
Start = {
|
Start = {
|
||||||
--rightside
|
--rightside
|
||||||
st = "Play shit idk",
|
st = "Basic play!",
|
||||||
st2 = "Play something blah blah blah blah\nWith newlines",
|
st2 = "Play whatever songs you like!\nComplete for high scores on an IR around the world.",
|
||||||
--leftside
|
--leftside
|
||||||
st3 = "Start",
|
st3 = "Start",
|
||||||
sc = "Scroll",
|
sc = "VOL to select",
|
||||||
desc = "Test description. Blah blah blah",
|
desc = "Test description. Blah blah blah",
|
||||||
},
|
},
|
||||||
Nautica = {
|
Nautica = {
|
||||||
--rightside
|
--rightside
|
||||||
dls = "Download more songs",
|
dls = "Download more songs!",
|
||||||
dls2 = "ksm.dev",
|
dls2 = "Get new charts from ksm.dev, updated daily!",
|
||||||
},
|
},
|
||||||
Settings = {
|
Settings = {
|
||||||
--rightside
|
--rightside
|
||||||
se = "Adjust things",
|
se = "Open settings!",
|
||||||
se1= "Open settings",
|
se1= "Tweak things to your liking.",
|
||||||
},
|
},
|
||||||
Exit = {
|
Exit = {
|
||||||
--rightside
|
--rightside
|
||||||
ex = "Leave this cursed game",
|
ex = "Close the game!",
|
||||||
ex2 = "C'mon press that button!\nYou know you want to do it",
|
ex2 = "Close the game and end this session.\nGoodbye!",
|
||||||
},
|
},
|
||||||
Result = {
|
Result = {
|
||||||
--leftside
|
--leftside
|
||||||
|
|
|
@ -51,6 +51,10 @@ local danBadgeImage = gfx.CreateSkinImage("dan/inf.png", 0);
|
||||||
local badgeLines = gfx.CreateSkinImage("result/badge_lines.png", 0);
|
local badgeLines = gfx.CreateSkinImage("result/badge_lines.png", 0);
|
||||||
local badgeGrade = gfx.CreateSkinImage("result/badge_gradient.png", 0);
|
local badgeGrade = gfx.CreateSkinImage("result/badge_gradient.png", 0);
|
||||||
|
|
||||||
|
local gaugeTypeMirrorImage = gfx.CreateSkinImage("result/gauge_type_badges/mirror.png", 0);
|
||||||
|
local gaugeTypeRandomImage = gfx.CreateSkinImage("result/gauge_type_badges/random.png", 0);
|
||||||
|
local gaugeTypeMirrorRandomImage = gfx.CreateSkinImage("result/gauge_type_badges/random_mirror.png", 0);
|
||||||
|
|
||||||
local gradeImages = {
|
local gradeImages = {
|
||||||
S = gfx.CreateSkinImage("common/grades/S.png", 0),
|
S = gfx.CreateSkinImage("common/grades/S.png", 0),
|
||||||
AAA_P = gfx.CreateSkinImage("common/grades/AAA+.png", 0),
|
AAA_P = gfx.CreateSkinImage("common/grades/AAA+.png", 0),
|
||||||
|
@ -176,6 +180,13 @@ local irText = ''
|
||||||
game.LoadSkinSample("result")
|
game.LoadSkinSample("result")
|
||||||
game.LoadSkinSample("shutter")
|
game.LoadSkinSample("shutter")
|
||||||
|
|
||||||
|
local function isHard(result)
|
||||||
|
if result.flags == nil then
|
||||||
|
return result.gauge_type == 1
|
||||||
|
end
|
||||||
|
return result.flags & 1 == 1
|
||||||
|
end
|
||||||
|
|
||||||
local handleSfx = function()
|
local handleSfx = function()
|
||||||
if not bgSfxPlayed then
|
if not bgSfxPlayed then
|
||||||
game.PlaySample("result", true)
|
game.PlaySample("result", true)
|
||||||
|
@ -184,6 +195,55 @@ local handleSfx = function()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local drawGraph = function(x,y,w,h)
|
||||||
|
if isHard(result) then
|
||||||
|
gfx.BeginPath()
|
||||||
|
gfx.Rect(x,y,w,103)
|
||||||
|
gfx.FillColor(26,26,26,255)
|
||||||
|
gfx.Fill()
|
||||||
|
gfx.FillColor(255,255,255,255)
|
||||||
|
else
|
||||||
|
gfx.BeginPath()
|
||||||
|
gfx.Rect(x,y,w,h-68)
|
||||||
|
gfx.FillColor(55,27,51,255)
|
||||||
|
gfx.Fill()
|
||||||
|
gfx.BeginPath()
|
||||||
|
gfx.Rect(x,y+30,w,72)
|
||||||
|
gfx.FillColor(7,24,28,255)
|
||||||
|
gfx.Fill()
|
||||||
|
gfx.FillColor(255,255,255,255)
|
||||||
|
end
|
||||||
|
|
||||||
|
gfx.BeginPath()
|
||||||
|
gfx.MoveTo(x,y + h + 2 - h * result.gaugeSamples[1])
|
||||||
|
for i = 2, #result.gaugeSamples do
|
||||||
|
gfx.LineTo(x + i * w / #result.gaugeSamples,y + h + 2 - h * result.gaugeSamples[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
if isHard(result) then
|
||||||
|
gfx.StrokeWidth(3)
|
||||||
|
gfx.StrokeColor(232,163,10)
|
||||||
|
gfx.Stroke()
|
||||||
|
gfx.Scissor(x, y + h *0.01, w, h*0.98)
|
||||||
|
gfx.Stroke()
|
||||||
|
gfx.ResetScissor()
|
||||||
|
gfx.Scissor(x, y + h * 0.99, w, (h * 0.03) + 4)
|
||||||
|
gfx.StrokeColor(255,0,0)
|
||||||
|
gfx.Stroke()
|
||||||
|
gfx.ResetScissor()
|
||||||
|
else
|
||||||
|
gfx.StrokeWidth(3)
|
||||||
|
gfx.StrokeColor(46,211,241)
|
||||||
|
gfx.Scissor(x, y + h * 0.3, w, (h * 0.7) + 4)
|
||||||
|
gfx.Stroke()
|
||||||
|
gfx.ResetScissor()
|
||||||
|
gfx.Scissor(x, y, w, h*0.3)
|
||||||
|
gfx.StrokeColor(215,48,182)
|
||||||
|
gfx.Stroke()
|
||||||
|
gfx.ResetScissor()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function drawTimingBar(y, value, max, type)
|
function drawTimingBar(y, value, max, type)
|
||||||
gfx.BeginPath();
|
gfx.BeginPath();
|
||||||
|
|
||||||
|
@ -401,6 +461,21 @@ local drawRightPanelContent = function()
|
||||||
gfx.Restore()
|
gfx.Restore()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Draw the gauge type flags if needed (mirror, random)
|
||||||
|
if(result.mirror or result.random) then
|
||||||
|
gfx.BeginPath();
|
||||||
|
local gaugeTypeFlagPosX = gaugePosX + 10;
|
||||||
|
local gaugeTypeFlagPosY = gaugePosY - 30;
|
||||||
|
local flagw, flagh = gfx.ImageSize(gaugeTypeMirrorImage)
|
||||||
|
if(result.mirror and result.random) then
|
||||||
|
gfx.ImageRect(gaugeTypeFlagPosX, gaugeTypeFlagPosY, flagw, flagh, gaugeTypeMirrorRandomImage, 1, 0)
|
||||||
|
elseif(result.mirror) then
|
||||||
|
gfx.ImageRect(gaugeTypeFlagPosX, gaugeTypeFlagPosY, flagw, flagh, gaugeTypeMirrorImage, 1, 0)
|
||||||
|
elseif(result.random) then
|
||||||
|
gfx.ImageRect(gaugeTypeFlagPosX, gaugeTypeFlagPosY, flagw, flagh, gaugeTypeRandomImage, 1, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Draw err/early/critical/late/err texts
|
-- Draw err/early/critical/late/err texts
|
||||||
|
|
||||||
gfx.Text(earlyLateBarsStats.earlyErrors, rightPanelX + 683,
|
gfx.Text(earlyLateBarsStats.earlyErrors, rightPanelX + 683,
|
||||||
|
@ -497,8 +572,23 @@ local drawBottomPanelContent = function(deltatime)
|
||||||
gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT + gfx.TEXT_ALIGN_MIDDLE)
|
gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT + gfx.TEXT_ALIGN_MIDDLE)
|
||||||
gfx.Text(result.medianHitDelta.." ms", rightX, baseY);
|
gfx.Text(result.medianHitDelta.." ms", rightX, baseY);
|
||||||
gfx.Text(math.floor(result.meanHitDelta).." ms", rightX, baseY + detailTextMargin);
|
gfx.Text(math.floor(result.meanHitDelta).." ms", rightX, baseY + detailTextMargin);
|
||||||
|
|
||||||
|
--Draw Graph
|
||||||
|
drawGraph(leftX-22, baseY-18, 454, 98);
|
||||||
|
|
||||||
|
--draw Recommended Offset
|
||||||
|
local delta = math.floor(result.medianHitDelta);
|
||||||
|
local songOffset = 0;
|
||||||
|
if (songOffset == nil) then songOffset = 0; end
|
||||||
|
local offset = tonumber(songOffset) + delta;
|
||||||
|
gfx.FillColor(255,255,255,255);
|
||||||
|
gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT + gfx.TEXT_ALIGN_TOP)
|
||||||
|
gfx.Text('RECOMMENDED SONG OFFSET:', leftX + 367, baseY + 89);
|
||||||
|
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_TOP)
|
||||||
|
gfx.Text(string.format("%dms", offset), leftX + 370, baseY + 89);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local drawJacketPanel = function()
|
local drawJacketPanel = function()
|
||||||
gfx.BeginPath();
|
gfx.BeginPath();
|
||||||
local tw, th = gfx.ImageSize(jacketPanelImage);
|
local tw, th = gfx.ImageSize(jacketPanelImage);
|
||||||
|
@ -508,10 +598,9 @@ end
|
||||||
|
|
||||||
local drawJacketPanelContent = function(deltaTime)
|
local drawJacketPanelContent = function(deltaTime)
|
||||||
gfx.BeginPath();
|
gfx.BeginPath();
|
||||||
gfx.ImageRect(jacketPanelX + 13, jacketPanelY + 28, 265, 265,
|
gfx.ImageRect(jacketPanelX + 13, jacketPanelY + 28, 265, 265, jacketImage or defaultJacketImage, 1, 0);
|
||||||
jacketImage or defaultJacketImage, 1, 0);
|
local adjustedDiff = GetDisplayDifficulty(result.jacketPath, result.difficulty)
|
||||||
|
DiffRectangle.render(deltaTime, jacketPanelX+183, jacketPanelY+2.5, 0.67, adjustedDiff, result.level);
|
||||||
DiffRectangle.render(deltaTime, jacketPanelX+183, jacketPanelY+2.5, 0.67, result.difficulty, result.level);
|
|
||||||
|
|
||||||
-- gfx.BeginPath();
|
-- gfx.BeginPath();
|
||||||
-- gfx.ImageRect(jacketPanelX + 183, jacketPanelY + 2.5, 140 / 1.5, 31 / 1.5,
|
-- gfx.ImageRect(jacketPanelX + 183, jacketPanelY + 2.5, 140 / 1.5, 31 / 1.5,
|
||||||
|
|
|
@ -143,7 +143,8 @@ local check_or_create_cache = function(challenge)
|
||||||
["title"] = gfx.CreateLabel(missing_text, defaultLabelSize, 0),
|
["title"] = gfx.CreateLabel(missing_text, defaultLabelSize, 0),
|
||||||
["title_raw"] = missing_text,
|
["title_raw"] = missing_text,
|
||||||
["level"] = 0,
|
["level"] = 0,
|
||||||
["difficulty"] = 0
|
["difficulty"] = 0,
|
||||||
|
["jacketPath"] = "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -- if not challenge.missing_chart then
|
else -- if not challenge.missing_chart then
|
||||||
|
@ -153,7 +154,8 @@ local check_or_create_cache = function(challenge)
|
||||||
["title"] = gfx.CreateLabel(chart.title, defaultLabelSize, 0),
|
["title"] = gfx.CreateLabel(chart.title, defaultLabelSize, 0),
|
||||||
["title_raw"] = chart.title,
|
["title_raw"] = chart.title,
|
||||||
["level"] = chart.level,
|
["level"] = chart.level,
|
||||||
["difficulty"] = chart.difficulty
|
["difficulty"] = chart.difficulty,
|
||||||
|
["jacketPath"] = chart.jacketPath,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
challengeCache[challenge.id]["charts"] = charts
|
challengeCache[challenge.id]["charts"] = charts
|
||||||
|
@ -403,8 +405,8 @@ draw_challenge = function(challenge, x, y, w, h, selected)
|
||||||
|
|
||||||
for i, chart in ipairs(challengeCache[challenge.id]["charts"]) do
|
for i, chart in ipairs(challengeCache[challenge.id]["charts"]) do
|
||||||
local ypos = offsetY + paddingY * (i - 1)
|
local ypos = offsetY + paddingY * (i - 1)
|
||||||
|
local adjustedDiff = GetDisplayDifficulty(chart.jacketPath, chart.difficulty)
|
||||||
DiffRectangle.render(timer, offsetX, ypos, diffIconScale, chart.difficulty, chart.level)
|
DiffRectangle.render(timer, offsetX, ypos, diffIconScale, adjustedDiff, chart.level)
|
||||||
|
|
||||||
local _, titleHeight = gfx.LabelSize(chart.title)
|
local _, titleHeight = gfx.LabelSize(chart.title)
|
||||||
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER | gfx.TEXT_ALIGN_MIDDLE)
|
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER | gfx.TEXT_ALIGN_MIDDLE)
|
||||||
|
|
|
@ -9,8 +9,8 @@ local defaultFolderBgImage = gfx.CreateSkinImage('song_select/filter_wheel/bg.pn
|
||||||
local collectionFolderBgImage = gfx.CreateSkinImage('song_select/filter_wheel/col_bg.png', 0)
|
local collectionFolderBgImage = gfx.CreateSkinImage('song_select/filter_wheel/col_bg.png', 0)
|
||||||
local subFolderBgImage = gfx.CreateSkinImage('song_select/filter_wheel/sub_bg.png', 0)
|
local subFolderBgImage = gfx.CreateSkinImage('song_select/filter_wheel/sub_bg.png', 0)
|
||||||
|
|
||||||
local scrollbarBgImage = gfx.CreateSkinImage("song_select/scrollbar/bg.png", 1)
|
local scrollBarBackgroundImage = gfx.CreateSkinImage("song_select/scrollbar/bg.png", 1)
|
||||||
local scrollbarFillImage = gfx.CreateSkinImage("song_select/scrollbar/fill.png", 1)
|
local scrollBarFillImage = gfx.CreateSkinImage("song_select/scrollbar/fill.png", 1)
|
||||||
|
|
||||||
local cursorImages = {
|
local cursorImages = {
|
||||||
gfx.CreateSkinImage("song_select/cursor.png", 1), -- Effective rate or fallback
|
gfx.CreateSkinImage("song_select/cursor.png", 1), -- Effective rate or fallback
|
||||||
|
@ -283,27 +283,39 @@ function drawScrollbar()
|
||||||
if not isFilterWheelActive or transitionLeaveScale ~= 0 then return end
|
if not isFilterWheelActive or transitionLeaveScale ~= 0 then return end
|
||||||
|
|
||||||
gfx.BeginPath()
|
gfx.BeginPath()
|
||||||
local bgW = 13*0.85;
|
local resize = 0.85;
|
||||||
local bgH = 1282*0.85;
|
local lw, lh = gfx.ImageSize(scrollBarBackgroundImage);
|
||||||
local scrollPosX = desw-20
|
local lw = lw * resize;
|
||||||
local scrollPosY = desh/2-bgH/2
|
local lh = lh * resize;
|
||||||
|
local xPos = desw-20
|
||||||
gfx.ImageRect(scrollPosX, scrollPosY, bgW, bgH, scrollbarBgImage, 1, 0)
|
local backgroundYPos = desh/2 - lh/2
|
||||||
|
gfx.ImageRect(xPos, backgroundYPos, lw, lh, scrollBarBackgroundImage, 1, 0)
|
||||||
local total = game.GetSkinSetting('_songWheelScrollbarTotal')
|
|
||||||
local index = game.GetSkinSetting('_songWheelScrollbarIndex')
|
|
||||||
|
|
||||||
if (index == nil) then return end;
|
|
||||||
|
|
||||||
gfx.BeginPath()
|
gfx.BeginPath()
|
||||||
local fillW = 27*0.85
|
local sw, sh = gfx.ImageSize(scrollBarFillImage);
|
||||||
local fillH = 65*0.85
|
local sw = sw * resize;
|
||||||
local fillPosOffsetY = (bgH-fillH)*(
|
local sh = sh * resize;
|
||||||
(index-1) /
|
local fillXPos = xPos - 6;
|
||||||
math.max(1,total-1)
|
|
||||||
)
|
|
||||||
|
|
||||||
gfx.ImageRect(scrollPosX-6, scrollPosY+fillPosOffsetY, fillW, fillH, scrollbarFillImage, 1, 0)
|
-- figure out index and total
|
||||||
|
local index = 1;
|
||||||
|
local total = 1;
|
||||||
|
if selectionMode == 'folders' then
|
||||||
|
index = selectedFolder
|
||||||
|
total = #filters.folder;
|
||||||
|
else
|
||||||
|
index = selectedLevel
|
||||||
|
total = #filters.level;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local minScrollYPos = backgroundYPos;
|
||||||
|
local maxScrollYPos = backgroundYPos + lh - sh;
|
||||||
|
local scrollStep = (maxScrollYPos - minScrollYPos) / (total - 1);
|
||||||
|
local scrollbarYOffset = (index - 1) * scrollStep;
|
||||||
|
local scrollbarYPos = minScrollYPos + scrollbarYOffset;
|
||||||
|
|
||||||
|
gfx.ImageRect(fillXPos, scrollbarYPos, sw, sh, scrollBarFillImage, 1, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
function tickTransitions(deltaTime)
|
function tickTransitions(deltaTime)
|
||||||
|
|
|
@ -27,13 +27,20 @@ local top50JacketOverlayImage = gfx.CreateSkinImage("song_select/top50_jacket.pn
|
||||||
|
|
||||||
local diffCursorImage = gfx.CreateSkinImage("song_select/level_cursor.png", 1)
|
local diffCursorImage = gfx.CreateSkinImage("song_select/level_cursor.png", 1)
|
||||||
|
|
||||||
|
local scrollBarBackgroundImage = gfx.CreateSkinImage("song_select/scrollbar/bg.png", 1)
|
||||||
|
local scrollBarFillImage = gfx.CreateSkinImage("song_select/scrollbar/fill.png", 1)
|
||||||
|
|
||||||
local filterInfoBgImage = gfx.CreateSkinImage("song_select/filter_info_bg.png", 1)
|
local filterInfoBgImage = gfx.CreateSkinImage("song_select/filter_info_bg.png", 1)
|
||||||
local sortInfoBgImage = gfx.CreateSkinImage("song_select/sort_info_bg.png", 1)
|
local sortInfoBgImage = gfx.CreateSkinImage("song_select/sort_info_bg.png", 1)
|
||||||
|
|
||||||
local searchBgImage = gfx.CreateSkinImage("song_select/search_bg.png", 1)
|
local searchBgImage = gfx.CreateSkinImage("song_select/search_bg.png", 1)
|
||||||
|
local searchActiveImage = gfx.CreateSkinImage("song_select/search_active.png", 1)
|
||||||
|
local searchInfoPanelImage = gfx.CreateSkinImage("song_select/search_info_panel.png", 1)
|
||||||
|
|
||||||
local defaultJacketImage = gfx.CreateSkinImage("song_select/loading.png", 0)
|
local defaultJacketImage = gfx.CreateSkinImage("song_select/loading.png", 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local difficultyLabelImages = {
|
local difficultyLabelImages = {
|
||||||
gfx.CreateSkinImage("song_select/plate/difficulty_labels/novice.png", 1),
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/novice.png", 1),
|
||||||
gfx.CreateSkinImage("song_select/plate/difficulty_labels/advanced.png", 1),
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/advanced.png", 1),
|
||||||
|
@ -141,6 +148,15 @@ local transitionJacketBgScrollScale = 0;
|
||||||
local transitionJacketBgScrollAlpha = 0;
|
local transitionJacketBgScrollAlpha = 0;
|
||||||
local transitionJacketBgScrollPosX = 0;
|
local transitionJacketBgScrollPosX = 0;
|
||||||
|
|
||||||
|
--search
|
||||||
|
local searchPreviousActiveState = false;
|
||||||
|
local searchInfoPreviousActiveState = false;
|
||||||
|
local transitionSearchEnterScale = 0;
|
||||||
|
local transitionSearchInfoEnterScale = 0;
|
||||||
|
local transitionSearchBackgroundAlpha = 0;
|
||||||
|
local transitionSearchbarOffsetY = 0;
|
||||||
|
local transitionSearchInfoOffsetY = 0;
|
||||||
|
|
||||||
local transitionLaserScale = 0;
|
local transitionLaserScale = 0;
|
||||||
local transitionLaserY = 0;
|
local transitionLaserY = 0;
|
||||||
|
|
||||||
|
@ -625,7 +641,7 @@ function drawFilterInfo(deltatime)
|
||||||
gfx.LoadSkinFont('NotoSans-Regular.ttf')
|
gfx.LoadSkinFont('NotoSans-Regular.ttf')
|
||||||
|
|
||||||
if (songwheel.searchInputActive) then
|
if (songwheel.searchInputActive) then
|
||||||
return;
|
--return;
|
||||||
end
|
end
|
||||||
|
|
||||||
gfx.BeginPath()
|
gfx.BeginPath()
|
||||||
|
@ -663,22 +679,115 @@ function drawCursor()
|
||||||
end
|
end
|
||||||
|
|
||||||
function drawSearch()
|
function drawSearch()
|
||||||
if (not songwheel.searchInputActive) then
|
if (not songwheel.searchInputActive and searchPreviousActiveState) then
|
||||||
|
searchPreviousActiveState = false;
|
||||||
|
game.PlaySample('sort_wheel/enter.wav');
|
||||||
|
elseif (songwheel.searchInputActive and not searchPreviousActiveState) then
|
||||||
|
searchPreviousActiveState = true;
|
||||||
|
game.PlaySample('sort_wheel/leave.wav');
|
||||||
|
end
|
||||||
|
|
||||||
|
if (songwheel.searchText ~= '' and searchInfoPreviousActiveState == true) then
|
||||||
|
searchInfoPreviousActiveState = false;
|
||||||
|
elseif (songwheel.searchText == '' and searchInfoPreviousActiveState == false) then
|
||||||
|
searchInfoPreviousActiveState = true;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (transitionSearchEnterScale == 0) then
|
||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Draw dark overlay over Songwheel
|
||||||
gfx.BeginPath();
|
gfx.BeginPath();
|
||||||
local tw, th = gfx.ImageSize(searchBgImage)
|
gfx.FillColor(0, 0, 0, math.floor(transitionSearchBackgroundAlpha * 192));
|
||||||
local xPos = desw-tw/2;
|
gfx.Rect(0, 0, 1080, 1920);
|
||||||
local yPos = 90;
|
gfx.Fill();
|
||||||
|
|
||||||
gfx.ImageRect(xPos, yPos, tw/2, th/2, searchBgImage, 1, 0)
|
-- Draw search info panel
|
||||||
|
gfx.BeginPath();
|
||||||
|
local infoResize = 0.855;
|
||||||
|
local sw, sh = gfx.ImageSize(searchInfoPanelImage)
|
||||||
|
sw = sw * infoResize;
|
||||||
|
sh = sh * infoResize;
|
||||||
|
local infoXPos = 0;
|
||||||
|
local infoYStartPos = desh - sh - 772 + 242;
|
||||||
|
local infoYPos = infoYStartPos + transitionSearchInfoOffsetY;
|
||||||
|
|
||||||
|
if (game.GetSkinSetting('gameplay_showSearchControls')) then
|
||||||
|
gfx.ImageRect(infoXPos, infoYPos, sw, sh, searchInfoPanelImage, transitionSearchBackgroundInfoAlpha, 0)
|
||||||
|
end
|
||||||
|
|
||||||
gfx.FontSize(32);
|
-- Draw Search is Active text
|
||||||
|
gfx.BeginPath();
|
||||||
|
local activeResize = 0.855;
|
||||||
|
local activew, activeh = gfx.ImageSize(searchActiveImage)
|
||||||
|
activew = activew * activeResize;
|
||||||
|
activeh = activeh * activeResize;
|
||||||
|
local activeXPos = 0;
|
||||||
|
local activeYStartPos = desh - sh - 722;
|
||||||
|
|
||||||
|
local activeYPos = activeYStartPos + transitionSearchInfoOffsetY;
|
||||||
|
gfx.ImageRect(activeXPos, activeYPos, activew, activeh, searchActiveImage, 1, 0);
|
||||||
|
|
||||||
|
-- Draw Searchbox
|
||||||
|
gfx.BeginPath();
|
||||||
|
local searchResize = 0.8;
|
||||||
|
local tw, th = gfx.ImageSize(searchBgImage);
|
||||||
|
tw = tw * searchResize;
|
||||||
|
th = th * searchResize;
|
||||||
|
local xPos = (desw-tw)/2;
|
||||||
|
local yStartPos = 170;
|
||||||
|
|
||||||
|
local yPos = yStartPos - transitionSearchbarOffsetY
|
||||||
|
|
||||||
|
gfx.ImageRect(xPos, yPos, tw, th, searchBgImage, 1, 0)
|
||||||
|
|
||||||
|
gfx.FontSize(48);
|
||||||
gfx.LoadSkinFont('Digital-Serial-Bold.ttf')
|
gfx.LoadSkinFont('Digital-Serial-Bold.ttf')
|
||||||
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE)
|
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE)
|
||||||
gfx.Text(songwheel.searchText, xPos+100, yPos+52);
|
gfx.Text(songwheel.searchText, xPos + 160, yPos + 83.2);
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawScrollbar()
|
||||||
|
if isFilterWheelActive or transitionLeaveScale ~= 0 then return end
|
||||||
|
|
||||||
|
-- Scrollbar Background
|
||||||
|
gfx.BeginPath()
|
||||||
|
local resize = 0.85;
|
||||||
|
local lw, lh = gfx.ImageSize(scrollBarBackgroundImage);
|
||||||
|
local lw = lw * resize;
|
||||||
|
local lh = lh * resize;
|
||||||
|
local xPos = desw-20
|
||||||
|
local backgroundYPos = desh/2 - lh/2
|
||||||
|
gfx.ImageRect(xPos, backgroundYPos, lw, lh, scrollBarBackgroundImage, 1, 0)
|
||||||
|
|
||||||
|
-- Scrollbar Fill
|
||||||
|
gfx.BeginPath()
|
||||||
|
local sw, sh = gfx.ImageSize(scrollBarFillImage);
|
||||||
|
local sw = sw * resize;
|
||||||
|
local sh = sh * resize;
|
||||||
|
local fillXPos = xPos - 6;
|
||||||
|
|
||||||
|
local minScrollYPos = backgroundYPos;
|
||||||
|
local maxScrollYPos = backgroundYPos + lh - sh;
|
||||||
|
local scrollStep = (maxScrollYPos - minScrollYPos) / (#songwheel.songs - 1);
|
||||||
|
local scrollbarYOffset = (selectedIndex - 1) * scrollStep;
|
||||||
|
local scrollbarYPos = minScrollYPos + scrollbarYOffset;
|
||||||
|
gfx.ImageRect(fillXPos, scrollbarYPos, sw, sh, scrollBarFillImage, 1, 0);
|
||||||
|
|
||||||
|
-- 1st letter of song title on scroll
|
||||||
|
gfx.BeginPath()
|
||||||
|
gfx.FontSize(16)
|
||||||
|
gfx.LoadSkinFont('Digital-Serial-Bold.ttf')
|
||||||
|
gfx.Rect(fillXPos-18, scrollbarYPos - 5, 16, 16)
|
||||||
|
gfx.FillColor(0,0,0,170)
|
||||||
|
gfx.Fill()
|
||||||
|
gfx.FillColor(255,255,255)
|
||||||
|
gfx.TextAlign(gfx.TEXT_ALIGN_MIDDLE + gfx.TEXT_ALIGN_CENTER)
|
||||||
|
if (songwheel.songs[selectedIndex] ~= nil) then
|
||||||
|
local letter = string.upper(common.firstLetter(songwheel.songs[selectedIndex].title));
|
||||||
|
gfx.Text(letter, fillXPos-10, scrollbarYPos + 5);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function refreshIrLeaderboard(deltaTime)
|
function refreshIrLeaderboard(deltaTime)
|
||||||
|
@ -787,6 +896,41 @@ function tickTransitions(deltaTime)
|
||||||
transitionAfterscrollDataOverlayAlpha = 1;
|
transitionAfterscrollDataOverlayAlpha = 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Searchbar offsets and alpha
|
||||||
|
if not searchPreviousActiveState then
|
||||||
|
if transitionSearchEnterScale > 0 then
|
||||||
|
transitionSearchEnterScale = transitionSearchEnterScale - deltaTime / 0.5 -- transition should last for that time in seconds
|
||||||
|
else
|
||||||
|
transitionSearchEnterScale = 0
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if transitionSearchEnterScale < 1 then
|
||||||
|
transitionSearchEnterScale = transitionSearchEnterScale + deltaTime / 0.5 -- transition should last for that time in seconds
|
||||||
|
else
|
||||||
|
transitionSearchEnterScale = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
transitionSearchInfoOffsetY = Easing.inOutQuad(1 - transitionSearchEnterScale) * 1680
|
||||||
|
transitionSearchbarOffsetY = Easing.inOutQuad(1 - transitionSearchEnterScale) * 300
|
||||||
|
transitionSearchBackgroundAlpha = Easing.inOutQuad(transitionSearchEnterScale)
|
||||||
|
|
||||||
|
if not searchInfoPreviousActiveState then
|
||||||
|
if transitionSearchInfoEnterScale > 0 then
|
||||||
|
transitionSearchInfoEnterScale = transitionSearchInfoEnterScale - deltaTime / 0.25 -- transition should last for that time in seconds
|
||||||
|
else
|
||||||
|
transitionSearchInfoEnterScale = 0
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if transitionSearchInfoEnterScale < 1 then
|
||||||
|
transitionSearchInfoEnterScale = transitionSearchInfoEnterScale + deltaTime / 0.25 -- transition should last for that time in seconds
|
||||||
|
else
|
||||||
|
transitionSearchInfoEnterScale = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
transitionSearchBackgroundInfoAlpha = Easing.inOutQuad(transitionSearchInfoEnterScale)
|
||||||
|
|
||||||
-- Grade alpha
|
-- Grade alpha
|
||||||
if transitionAfterscrollScale >= 0.03 and transitionAfterscrollScale < 0.033 then
|
if transitionAfterscrollScale >= 0.03 and transitionAfterscrollScale < 0.033 then
|
||||||
transitionAfterscrollGradeAlpha = 0.5;
|
transitionAfterscrollGradeAlpha = 0.5;
|
||||||
|
@ -932,6 +1076,8 @@ draw_songwheel = function(x,y,w,h, deltaTime)
|
||||||
|
|
||||||
drawSearch();
|
drawSearch();
|
||||||
|
|
||||||
|
drawScrollbar();
|
||||||
|
|
||||||
gfx.BeginPath();
|
gfx.BeginPath();
|
||||||
gfx.FontSize(18)
|
gfx.FontSize(18)
|
||||||
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_TOP)
|
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_TOP)
|
||||||
|
|
|
@ -16,5 +16,5 @@ uniform mat4 world;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
fsTex = inTex;
|
fsTex = inTex;
|
||||||
gl_Position = proj * camera * world * vec4(inPos.x, inPos.y * 3.5, 0, 1);
|
gl_Position = proj * camera * world * vec4(inPos.x, inPos.y * 3.8, 0, 1);
|
||||||
}
|
}
|
|
@ -12,4 +12,10 @@ Custom crew assets
|
||||||
|
|
||||||
Clean up so no part of your custom crew is outside of frame_metal.png.
|
Clean up so no part of your custom crew is outside of frame_metal.png.
|
||||||
|
|
||||||
|
For added effect, apply this transformation to the crew portrait (in Paint.net ONLY, using zoom/rotate tool)
|
||||||
|
|
||||||
|
0.00
|
||||||
|
11.31
|
||||||
|
19.38
|
||||||
|
|
||||||
EXPORT AS .PNG FILE!
|
EXPORT AS .PNG FILE!
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 210 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 1.1 MiB |