WIP: the biggest chalwheel commit you will see from me

This commit is contained in:
Hersi 2021-11-20 22:54:47 +01:00
parent b25d92bf5c
commit 543b6dfe94
1 changed files with 276 additions and 131 deletions

View File

@ -14,7 +14,6 @@ local jacket = nil;
local selectedIndex = 1
local selectedDiff = 1
local challengeCache = {}
local ioffset = 0
local doffset = 0
local soffset = 0
local diffColors = { { 0, 0, 255 }, { 0, 255, 0 }, { 255, 0, 0 }, { 255, 0, 255 } }
@ -26,6 +25,7 @@ local searchText = gfx.CreateLabel("", 5, 0)
local searchIndex = 1
local backgroundImage = gfx.CreateSkinImage("challenge_select/bg.png", 0)
local challengeCardBG = gfx.CreateSkinImage("challenge_select/small_box.png", 0)
local jacketFallback = gfx.CreateSkinImage("song_select/loading.png", 0)
local showGuide = game.GetSkinSetting("show_guide")
@ -82,13 +82,20 @@ local badges = {
gfx.CreateSkinImage("song_select/medal/puc.png", 1)
}
local passStates = {
gfx.CreateSkinImage("challenge_select/pass_states/not_played.png", 0),
gfx.CreateSkinImage("challenge_select/pass_states/failed.png", 0),
gfx.CreateSkinImage("challenge_select/pass_states/cleared.png", 0),
}
gfx.LoadSkinFont("divlit_custom.ttf")
gfx.LoadSkinFont("dfmarugoth.ttf");
game.LoadSkinSample("menu_click")
game.LoadSkinSample("click-02")
game.LoadSkinSample("woosh")
local wheelSize = 6
local wheelSize = 5
get_page_size = function()
return math.floor(wheelSize / 2)
@ -96,11 +103,11 @@ end
-- Responsive UI variables
-- Aspect Ratios
local aspectFloat = 1.850
local aspectFloat = 1.0
local aspectRatio = "widescreen"
local landscapeWidescreenRatio = 1.850
local landscapeStandardRatio = 1.500
local portraitWidescreenRatio = 0.5
local landscapeWidescreenRatio = 16 / 9
local landscapeStandardRatio = 4 / 3
local portraitWidescreenRatio = 9 / 16
-- Responsive sizes
local fifthX = 0
@ -116,7 +123,7 @@ local halfY = 0
local fullY = 0
adjustScreen = function(x, y)
local a = x / y;
aspectFloat = x / y;
fifthX = x / 5
fourthX = x / 4
thirdX = x / 3
@ -130,55 +137,63 @@ adjustScreen = function(x, y)
fullY = y
end
check_or_create_cache = function(challenge, full)
check_or_create_cache = function(challenge)
local namesLabelSize = 20
local percentLabelSize = 35
if not challengeCache[challenge.id] then
challengeCache[challenge.id] = {}
end
if not challengeCache[challenge.id]["title"] then
challengeCache[challenge.id]["title"] = gfx.CreateLabel(challenge.title, 30, 0)
challengeCache[challenge.id]["title"] = gfx.CreateLabel(challenge.title, namesLabelSize, 0)
end
if not challengeCache[challenge.id]["chart_names"] then
local names = "Charts:"
for _, chart in ipairs(challenge.charts) do
names = names .. " [" .. chart.title .. "]"
end
if not challengeCache[challenge.id]["charts"] then
if challenge.missing_chart then
names = names .. " *COULD NOT FIND ALL CHARTS!*"
local missing_text = "*COULD NOT FIND ALL CHARTS!*"
challengeCache[challenge.id]["charts"] = {
{
["title"] = gfx.CreateLabel(missing_text, namesLabelSize, 0),
["level"] = 0,
["difficulty"] = 0
},
}
end
challengeCache[challenge.id]["chart_names"] = gfx.CreateLabel(names, 20, 0)
local charts = {}
for _, chart in ipairs(challenge.charts) do
table.insert(charts, {
["title"] = gfx.CreateLabel(chart.title, namesLabelSize, 0),
["level"] = chart.level,
["difficulty"] = chart.difficulty
})
end
if challenge.topBadge ~= 0
and (not challengeCache[challenge.id]["percent"] or not challengeCache[challenge.id]["percent_value"]
or challengeCache[challenge.id]["percent_value"] ~= challenge.bestScore) then
challengeCache[challenge.id]["percent"] = gfx.CreateLabel(
string.format(
"%u%%", math.max(0, (challenge.bestScore - 8000000) // 10000)
), 35, 0
)
challengeCache[challenge.id]["percent_value"] = challenge.bestScore
challengeCache[challenge.id]["charts"] = charts
end
if full then
if (not challengeCache[challenge.id]["percent"]
or not challengeCache[challenge.id]["total_score"]
or challengeCache[challenge.id]["total_score"] ~= challenge.bestScore) then
challengeCache[challenge.id]["percent"] = math.max(0, (challenge.bestScore - 8000000) // 10000)
challengeCache[challenge.id]["total_score"] = challenge.bestScore
end
if not challengeCache[challenge.id]["pass_state"] then
local passState = math.min(challenge.topBadge, 2) + 1 --challenge.topBadge -> [1, 3]
challengeCache[challenge.id]["pass_state"] = passStates[passState]
end
if not challengeCache[challenge.id]["jackets"] then
local jackets = {}
for i, chart in ipairs(challenge.charts) do
jackets[i] = gfx.LoadImageJob(chart.jacketPath, jacketFallback, 200, 200)
end
if #jackets == 0 then
jackets[1] = jacketFallback
end
challengeCache[challenge.id]["jackets"] = jackets
end
if not challengeCache[challenge.id]["desc"] then
local desc = "\n"
for _, chart in ipairs(challenge.charts) do
desc = desc .. "" .. chart.title .. "\n\n"
end
if challenge.missing_chart then
desc = desc .. "*COULD NOT FIND ALL CHARTS!*\n\n"
end
desc = desc .. ""
challengeCache[challenge.id]["desc"] = gfx.CreateLabel(desc, 20, 0)
end
end
end
draw_scores = function(difficulty, x, y, w, h)
@ -218,6 +233,7 @@ draw_challenge = function(challenge, x, y, w, h, selected)
check_or_create_cache(challenge)
--[[
gfx.BeginPath()
gfx.RoundedRectVarying(x,y, w, h,0,0,0,40)
gfx.FillColor(30, 30, 30)
@ -241,73 +257,121 @@ draw_challenge = function(challenge, x, y, w, h, selected)
--gfx.DrawLabel(challengeCache[challenge.id]["artist"], x+20, y + 50, w-10)
gfx.ForceRender()
--]]
end
draw_diff_icon = function(diff, x, y, w, h, selected, deltaTime)
local shrinkX = w / 4
local shrinkY = h / 4
--[[
gfx.Save()
gfx.BeginPath()
gfx.StrokeColor(255,0,0)
if selected then
gfx.FontSize(h / 2)
shrinkX = w / 6
shrinkY = h / 6
else
gfx.FontSize(math.floor(h / 3))
gfx.StrokeColor(255,255,0)
end
gfx.BeginPath()
gfx.RoundedRectVarying(x + shrinkX, y + shrinkY, w - shrinkX * 2, h - shrinkY * 2, 0, 0, 0, 0)
gfx.FillColor(15, 15, 15)
gfx.StrokeColor(table.unpack(diffColors[diff.difficulty + 1]))
gfx.StrokeWidth(2)
gfx.Fill()
gfx.Rect(x,y,w,h)
gfx.Stroke()
gfx.FillColor(255, 255, 255)
gfx.TextAlign(gfx.TEXT_ALIGN_MIDDLE + gfx.TEXT_ALIGN_CENTER)
gfx.FastText(tostring(diff.level), x + (w / 2), y + (h / 2))
-- gfx.BeginPath()
-- DiffRectangle.render(deltaTime, 183, 2.5, 10, songCache[song.id][selectedDiff],tostring(diff.level));
end
gfx.Restore()
--]]
draw_diffs = function(diffs, x, y, w, h)
local diffWidth = w / 2.5
local diffHeight = w / 2.5
local diffCount = #diffs
gfx.Scissor(x, y, w, h)
for i = math.max(selectedDiff - 2, 1), math.max(selectedDiff - 1, 1) do
local diff = diffs[i]
local xpos = x + ((w / 2 - diffWidth / 2) + (selectedDiff - i + doffset) * (-0.8 * diffWidth))
if i ~= selectedDiff then
draw_diff_icon(diff, xpos, y, diffWidth, diffHeight, false)
end
end
-- after selected
for i = math.min(selectedDiff + 2, diffCount), selectedDiff + 1, -1 do
local diff = diffs[i]
local xpos = x + ((w / 2 - diffWidth / 2) + (selectedDiff - i + doffset) * (-0.8 * diffWidth))
if i ~= selectedDiff then
draw_diff_icon(diff, xpos, y, diffWidth, diffHeight, false)
end
end
local diff = diffs[selectedDiff]
local xpos = x + ((w / 2 - diffWidth / 2) + (doffset) * (-0.8 * diffWidth))
draw_diff_icon(diff, xpos, y, diffWidth, diffHeight, true)
local testBox = function (xpos, ypos, width, height, value)
local textSize = 24
gfx.BeginPath()
gfx.FillColor(0, 128, 255)
gfx.Rect(x, y + 10, 2, diffHeight - h / 6)
gfx.Fill()
gfx.BeginPath()
gfx.Rect(x + w - 2, y + 10, 2, diffHeight - h / 6)
gfx.Fill()
gfx.ResetScissor()
draw_cursor(x + w / 2, y + diffHeight / 2, timer * math.pi, diffHeight / 1.5)
if value then
gfx.FontSize(textSize)
gfx.TextAlign(gfx.TEXT_ALIGN_MIDDLE | gfx.TEXT_ALIGN_CENTER)
gfx.Text(tostring(value), xpos + width / 2, ypos + height / 2)
end
draw_selected = function(challenge, x, y, w, h)
if not challenge then return end
gfx.StrokeColor(0,255,255)
gfx.Rect(xpos, ypos, width, height)
gfx.Stroke()
check_or_create_cache(challenge, true)
gfx.ForceRender()
end
local _draw_card_bg = function ()
gfx.BeginPath()
gfx.ImageRect(x, y, w, h, challengeCardBG, 1, 0)
end
local _draw_info = function ()
local stateLabel = challengeCache[challenge.id]["pass_state"]
local stateLabelWidth, stateLabelHeight = gfx.ImageSize(stateLabel)
local stateLabelAspect = stateLabelWidth / stateLabelHeight
local stateWidth = w / 5
local stateHeight = stateWidth / stateLabelAspect
local stateOffsetX = x + w / 32
local stateOffsetY = y + h / 16
local titleMargin = 6
local titleMaxWidth = 3/5 * w
local titleCenterX = x + w - titleMargin - titleMaxWidth/2 --align right
local titleOffsetY = y + 1/11 * h --align baseline
if not selected then
stateWidth = stateWidth * 0.9
stateHeight = stateHeight * 0.9
stateOffsetY = y + h / 32
titleMaxWidth = 6/9 * w
titleCenterX = x + w - titleMargin - titleMaxWidth/2 --align right
titleOffsetY = y + titleMargin/2 --align baseline
end
gfx.BeginPath()
gfx.ImageRect(stateOffsetX, stateOffsetY, stateWidth, stateHeight, stateLabel, 1, 0)
--testBox(stateOffsetX, stateOffsetY, stateWidth, stateHeight)
gfx.FontFace("divlit_custom.ttf")
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER | gfx.TEXT_ALIGN_BASELINE)
gfx.DrawLabel(challengeCache[challenge.id]["title"], titleCenterX, titleOffsetY, titleMaxWidth)
--testBox(titleOffsetX, titleOffsetY, math.min(titleLabelWidth, titleMaxWidth), titleLabelHeight)
end
local _draw_jacket = function ()
local size = h * 0.68
local offsetX = x + w / 32
local offsetY = y + h - size - h * 0.05
if not selected then
size = h * 0.66
offsetX = x + w * 0.058
offsetY = y + h - size - h * 0.066
end
gfx.BeginPath()
gfx.ImageRect(offsetX, offsetY, size, size, challengeCache[challenge.id]["jackets"][1], 1, 0)
end
local _draw_stats = function ()
local percentOffsetX = x + 5/9 * w
local percentOffsetY = y + 5/6 * h
local scoreOffsetX = x
local scoreOffsetY = y
gfx.BeginPath()
gfx.FontFace("divlit_custom.ttf")
gfx.FontSize(56)
gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT)
gfx.Text(challengeCache[challenge.id]["percent"], percentOffsetX - 24, percentOffsetY)
gfx.FontSize(32)
gfx.Text("%", percentOffsetX, percentOffsetY)
end
local _draw_chart = function ()
end
if not selected then
_draw_card_bg()
end
_draw_info()
_draw_jacket()
_draw_stats()
--[[
-- set up padding and margins
local xPadding = math.floor(w / 16)
local yPadding = math.floor(h / 32)
@ -329,6 +393,7 @@ draw_selected = function(challenge, x, y, w, h)
-- jacket should take up 1/3 of height, always be square, and be centered
local imageSize = math.floor((height / 2) * 2) - 10
local imageXPos = x + xMargin + xPadding
local imageYPos = y + yMargin + yPadding
local square_size = math.ceil(math.sqrt(#challenge.charts))
local origImageSize = imageSize
@ -347,7 +412,7 @@ draw_selected = function(challenge, x, y, w, h)
xoff = xoff
end
gfx.ImageRect(
62.52, 888.6 + (img_row / 200 * imageSize), imageSize * 1.19, imageSize * 1.19,
imageXPos, imageYPos + (img_row / 200 * imageSize), imageSize * 1.19, imageSize * 1.19,
challengeCache[challenge.id]["jackets"][i], 1, 0
)
img_col = img_col + 1
@ -451,41 +516,121 @@ draw_selected = function(challenge, x, y, w, h)
-- else
-- draw_scores(diff, xpos, (height/6)*5, width, (height/6))
-- end
--]]
gfx.ForceRender()
end
draw_challengewheel = function(x, y, w, h)
local offsetX = fifthX / 2
local width = math.floor((w / 5) * 4)
local height = math.floor((h / wheelSize) * 1.5)
draw_diff_icon = function(diff, x, y, w, h, selected, deltaTime)
local shrinkX = w / 4
local shrinkY = h / 4
if selected then
gfx.FontSize(h / 2)
shrinkX = w / 6
shrinkY = h / 6
else
gfx.FontSize(math.floor(h / 3))
end
gfx.BeginPath()
gfx.RoundedRectVarying(x + shrinkX, y + shrinkY, w - shrinkX * 2, h - shrinkY * 2, 0, 0, 0, 0)
gfx.FillColor(15, 15, 15)
gfx.StrokeColor(table.unpack(diffColors[diff.difficulty + 1]))
gfx.StrokeWidth(2)
gfx.Fill()
gfx.Stroke()
gfx.FillColor(255, 255, 255)
gfx.TextAlign(gfx.TEXT_ALIGN_MIDDLE + gfx.TEXT_ALIGN_CENTER)
gfx.FastText(tostring(diff.level), x + (w / 2), y + (h / 2))
-- gfx.BeginPath()
-- DiffRectangle.render(deltaTime, 183, 2.5, 10, songCache[song.id][selectedDiff],tostring(diff.level));
end
-- before selected
for i = math.max(selectedIndex - wheelSize / 2, 1), math.max(selectedIndex - 1, 0) do
local challenge = chalwheel.challenges[i]
local xpos = x + offsetX + ((selectedIndex - i + ioffset) ^ 2) * 3
local offsetY = (selectedIndex - i + ioffset)
* (height - (wheelSize / 2 * ((selectedIndex - i + ioffset) * aspectFloat)))
local ypos = y + ((h / 2 - height / 2) - offsetY)
draw_challenge(challenge, xpos, ypos, width, height)
draw_diffs = function(diffs, x, y, w, h)
local diffWidth = w / 2.5
local diffHeight = w / 2.5
local diffCount = #diffs
gfx.Scissor(x, y, w, h)
for i = math.max(selectedDiff - 2, 1), math.max(selectedDiff - 1, 1) do
local diff = diffs[i]
local xpos = x + ((w / 2 - diffWidth / 2) + (selectedDiff - i + doffset) * (-0.8 * diffWidth))
if i ~= selectedDiff then
draw_diff_icon(diff, xpos, y, diffWidth, diffHeight, false)
end
end
-- after selected
for i = math.min(selectedIndex + wheelSize / 2, #chalwheel.challenges), selectedIndex + 1, -1 do
local challenge = chalwheel.challenges[i]
local xpos = x + offsetX + ((i - selectedIndex - ioffset) ^ 2) * 2
local offsetY = (selectedIndex - i + ioffset)
* (height - (wheelSize / 2 * ((i - selectedIndex - ioffset) * aspectFloat)))
local ypos = y + ((h / 2 - height / 2) - (selectedIndex - i) - offsetY)
local alpha = 255 - (selectedIndex - i + ioffset) * 31
draw_challenge(challenge, xpos, ypos, width, height)
for i = math.min(selectedDiff + 2, diffCount), selectedDiff + 1, -1 do
local diff = diffs[i]
local xpos = x + ((w / 2 - diffWidth / 2) + (selectedDiff - i + doffset) * (-0.8 * diffWidth))
if i ~= selectedDiff then
draw_diff_icon(diff, xpos, y, diffWidth, diffHeight, false)
end
end
local diff = diffs[selectedDiff]
local xpos = x + ((w / 2 - diffWidth / 2) + (doffset) * (-0.8 * diffWidth))
draw_diff_icon(diff, xpos, y, diffWidth, diffHeight, true)
gfx.BeginPath()
gfx.FillColor(0, 128, 255)
gfx.Rect(x, y + 10, 2, diffHeight - h / 6)
gfx.Fill()
gfx.BeginPath()
gfx.Rect(x + w - 2, y + 10, 2, diffHeight - h / 6)
gfx.Fill()
gfx.ResetScissor()
draw_cursor(x + w / 2, y + diffHeight / 2, timer * math.pi, diffHeight / 1.5)
end
-- draw selected
local xpos = x + offsetX / 1.2 + ((-ioffset) ^ 2) * 2
local offsetY = (ioffset) * (height - (wheelSize / 2 * ((1) * aspectFloat)))
local ypos = y + ((h / 2 - height / 2) - (ioffset) - offsetY)
draw_challenge(chalwheel.challenges[selectedIndex], xpos, ypos, width, height, true)
return chalwheel.challenges[selectedIndex]
draw_selected = function(challenge, x, y, w, h)
if not challenge then return end
check_or_create_cache(challenge)
draw_challenge(challenge, x, y, w, h, true)
end
draw_chalwheel = function(x, y, w, h)
local challengeAspect = 4.367
local selectedChallengeAspect = 3.305
local portraitAspectCorrection = portraitWidescreenRatio / aspectFloat
local width = math.floor(w * 0.839)
local height = math.floor((width / challengeAspect) * portraitAspectCorrection)
local selectedWidth = math.floor(w * 0.944)
local selectedHeight = math.floor((selectedWidth / selectedChallengeAspect) * portraitAspectCorrection)
local offsetX = w / 2 - width / 2 --center
local centerY = h / 2 - height / 2
local selectedOffsetX = w / 2 - selectedWidth / 2
local selectedCenterY = h / 2 - selectedHeight / 2
local margin = h / 128
local centerMargin = h / 100
local imin = math.ceil(selectedIndex - wheelSize / 2)
local imax = math.floor(selectedIndex + wheelSize / 2)
for i = math.max(imin, 1), math.min(imax, #chalwheel.challenges) do
local current = selectedIndex - i
if not (current == 0) then
local challenge = chalwheel.challenges[i]
local xpos = x + offsetX
--local offsetY = current * (height - (wheelSize / 2 * (current * aspectFloat)))
local offsetY = math.abs(current) * (height + margin) + (selectedHeight - height) / 2
local ypos = y + centerY
if current < 0 then
ypos = ypos + centerMargin + offsetY
else -- if current > 0 then
ypos = ypos - centerMargin - offsetY
end
draw_challenge(challenge, xpos, ypos, width, height)
end
end
-- render selected song information
local xpos = x + selectedOffsetX
local ypos = y + selectedCenterY
draw_selected(chalwheel.challenges[selectedIndex], xpos, ypos, selectedWidth, selectedHeight)
end
draw_legend_pane = function(x, y, w, h, obj)
@ -565,21 +710,21 @@ render = function(deltaTime)
gfx.FontSize(40);
gfx.FillColor(255, 255, 255);
if chalwheel.challenges and chalwheel.challenges[1] then
-- draw chalwheel and get selected song
local song = draw_challengewheel(0, 0, fullX, fullY)
-- render selected song information
draw_selected(song, 0, 0, fullX, fifthY)
-- draw chalwheel
draw_chalwheel(0, 0, fullX, fullY)
end
-- Draw Legend Information
--[[
if showGuide then
draw_legend(0, (fifthY / 3) * 14, fullX, (fifthY / 3) * 1)
end
--]]
-- draw text search
--[[
draw_search(fifthX * 2, 5, fifthX * 3, fifthY / 5)
ioffset = ioffset * 0.9
doffset = doffset * 0.9
soffset = soffset * 0.8
if chalwheel.searchStatus then
@ -592,6 +737,7 @@ render = function(deltaTime)
gfx.LoadSkinFont("dfmarugoth.ttf");
gfx.ResetTransform()
gfx.ForceRender()
--]]
end
set_index = function(newIndex, scrollamt)
@ -599,7 +745,6 @@ set_index = function(newIndex, scrollamt)
game.PlaySample("menu_click")
scrollmulOffset = 0
end
ioffset = ioffset + selectedIndex - newIndex
selectedIndex = newIndex
scrollmul = scrollamt + scrollmulOffset
end;