Merge branch 'master' into titlescreen-refactor
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
require "common.class"
|
||||||
|
|
||||||
|
require "api.graphics"
|
||||||
|
|
||||||
|
local Image = require "api.image"
|
||||||
|
|
||||||
|
---@class AnimationParams
|
||||||
|
---@field fps number?
|
||||||
|
---@field loop boolean?
|
||||||
|
---@field loopPoint integer?
|
||||||
|
---@field width number?
|
||||||
|
---@field height number?
|
||||||
|
---@field x number?
|
||||||
|
---@field y number?
|
||||||
|
---@field scaleX number?
|
||||||
|
---@field scaleY number?
|
||||||
|
---@field centered boolean?
|
||||||
|
---@field blendOp integer?
|
||||||
|
---@field color number[]?
|
||||||
|
---@field alpha number?
|
||||||
|
---@field stroke StrokeParams?
|
||||||
|
|
||||||
|
---@class Animation
|
||||||
|
---@field frames Image[]
|
||||||
|
---@field frameCount integer
|
||||||
|
---@field frameTime number
|
||||||
|
---@field loop boolean
|
||||||
|
---@field loopPoint integer
|
||||||
|
---@field width number?
|
||||||
|
---@field height number?
|
||||||
|
---@field x number?
|
||||||
|
---@field y number?
|
||||||
|
---@field scaleX number?
|
||||||
|
---@field scaleY number?
|
||||||
|
---@field centered boolean?
|
||||||
|
---@field blendOp integer?
|
||||||
|
---@field color number[]?
|
||||||
|
---@field alpha number?
|
||||||
|
---@field stroke StrokeParams?
|
||||||
|
local Animation = { };
|
||||||
|
|
||||||
|
---@class AnimationState
|
||||||
|
---@field animation Animation # The animation data this state is playing through
|
||||||
|
---@field frameIndex integer # Current frame in the animation
|
||||||
|
---@field timer number # Timer used to determine when to change to the next frame
|
||||||
|
---@field running boolean # Is the animation currently running and accepting updates?
|
||||||
|
---@field callback function? # Called when the animation completes
|
||||||
|
local AnimationState = { };
|
||||||
|
|
||||||
|
local function loadSequentialAnimationFrames(animPath)
|
||||||
|
local frames = { };
|
||||||
|
local count = 0;
|
||||||
|
|
||||||
|
local detectedFormat = nil;
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
local frame = nil;
|
||||||
|
if (detectedFormat) then
|
||||||
|
frame = Image.new(detectedFormat:format(animPath, count + 1), true);
|
||||||
|
else
|
||||||
|
for i = 1, 4 do
|
||||||
|
local format = '%s/%0' .. i .. 'd.png';
|
||||||
|
frame = Image.new(format:format(animPath, count + 1), true);
|
||||||
|
|
||||||
|
if (frame) then
|
||||||
|
detectedFormat = format;
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (not frame) then
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
|
||||||
|
count = count + 1;
|
||||||
|
frames[count] = frame;
|
||||||
|
end
|
||||||
|
|
||||||
|
return frames, count;
|
||||||
|
end
|
||||||
|
|
||||||
|
---Animation constructor
|
||||||
|
---@param animPath string
|
||||||
|
---@param params AnimationParams
|
||||||
|
---@return Animation
|
||||||
|
function Animation.new(animPath, params)
|
||||||
|
local frames, frameCount = loadSequentialAnimationFrames(animPath);
|
||||||
|
|
||||||
|
local instance = {
|
||||||
|
frames = frames,
|
||||||
|
frameCount = frameCount,
|
||||||
|
|
||||||
|
frameTime = 1 / (params.fps or 30),
|
||||||
|
loop = params.loop or false,
|
||||||
|
loopPoint = params.loopPoint or 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (params.width ~= nil) then instance.width = params.width; end
|
||||||
|
if (params.height ~= nil) then instance.height = params.height; end
|
||||||
|
if (params.x ~= nil) then instance.x = params.x; end
|
||||||
|
if (params.y ~= nil) then instance.y = params.y; end
|
||||||
|
if (params.scaleX ~= nil) then instance.scaleX = params.scaleX; end
|
||||||
|
if (params.scaleY ~= nil) then instance.scaleY = params.scaleY; end
|
||||||
|
if (params.centered ~= nil) then instance.centered = params.centered; end
|
||||||
|
if (params.blendOp ~= nil) then instance.blendOp = params.blendOp; end
|
||||||
|
if (params.color ~= nil) then instance.color = params.color; end
|
||||||
|
if (params.alpha ~= nil) then instance.alpha = params.alpha; end
|
||||||
|
if (params.stroke ~= nil) then instance.stroke = params.stroke; end
|
||||||
|
|
||||||
|
return Base(Animation, instance);
|
||||||
|
end
|
||||||
|
|
||||||
|
---Create an AnimationState to play this animation.
|
||||||
|
---The AnimationState is not started.
|
||||||
|
---@param callback function?
|
||||||
|
---@return AnimationState
|
||||||
|
function Animation:createState(callback)
|
||||||
|
---@type AnimationState
|
||||||
|
local state = { animation = self, callback = callback, frameIndex = 1, timer = 0, running = false };
|
||||||
|
return Base(AnimationState, state);
|
||||||
|
end
|
||||||
|
|
||||||
|
---Create an AnimationState to play this animation and start it.
|
||||||
|
---@param callback function?
|
||||||
|
---@return AnimationState
|
||||||
|
function Animation:start(callback)
|
||||||
|
local state = self:createState(callback);
|
||||||
|
state:start();
|
||||||
|
|
||||||
|
return state;
|
||||||
|
end
|
||||||
|
|
||||||
|
---Start this AnimationState.
|
||||||
|
---Does nothing if it's already running.
|
||||||
|
function AnimationState:start()
|
||||||
|
self.running = true;
|
||||||
|
end
|
||||||
|
|
||||||
|
---Restart this AnimationState.
|
||||||
|
---The frame index is reset to 1.
|
||||||
|
function AnimationState:restart()
|
||||||
|
self.running = true;
|
||||||
|
self.frameIndex = 1;
|
||||||
|
self.timer = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
---Stop this AnimationState.
|
||||||
|
function AnimationState:stop()
|
||||||
|
self.running = false;
|
||||||
|
end
|
||||||
|
|
||||||
|
---Updates this AnimationState and then rendersit, passing on the given ImageParams to each frame.
|
||||||
|
---@param deltaTime number
|
||||||
|
---@param params? ImageParams
|
||||||
|
function AnimationState:render(deltaTime, params)
|
||||||
|
if (not self.running) then return; end;
|
||||||
|
|
||||||
|
self.timer = self.timer + deltaTime;
|
||||||
|
|
||||||
|
while (self.timer > self.animation.frameTime) do
|
||||||
|
self.timer = self.timer - self.animation.frameTime;
|
||||||
|
self.frameIndex = self.frameIndex + 1;
|
||||||
|
|
||||||
|
if (self.frameIndex > self.animation.frameCount) then
|
||||||
|
if (self.animation.loop) then
|
||||||
|
self.frameIndex = self.animation.loopPoint;
|
||||||
|
else
|
||||||
|
self.running = false;
|
||||||
|
|
||||||
|
if (self.callback) then
|
||||||
|
self.callback();
|
||||||
|
end
|
||||||
|
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (params) then
|
||||||
|
if (params.width == nil) then params.width = self.animation.width; end
|
||||||
|
if (params.height == nil) then params.height = self.animation.height; end
|
||||||
|
if (params.x == nil) then params.x = self.animation.x; end
|
||||||
|
if (params.y == nil) then params.y = self.animation.y; end
|
||||||
|
if (params.scaleX == nil) then params.scaleX = self.animation.scaleX; end
|
||||||
|
if (params.scaleY == nil) then params.scaleY = self.animation.scaleY; end
|
||||||
|
if (params.centered == nil) then params.centered = self.animation.centered; end
|
||||||
|
if (params.blendOp == nil) then params.blendOp = self.animation.blendOp; end
|
||||||
|
if (params.alpha == nil) then params.alpha = self.animation.alpha; end
|
||||||
|
if (params.stroke == nil) then params.stroke = self.animation.stroke; end
|
||||||
|
end
|
||||||
|
|
||||||
|
local frame = self.animation.frames[self.frameIndex];
|
||||||
|
if (not frame) then
|
||||||
|
-- TODO(local): what do
|
||||||
|
else
|
||||||
|
frame:render(params);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Animation;
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
-- TODO(local): put these class types somewhere more common
|
||||||
|
---@class StrokeParams
|
||||||
|
---@field color number[]?
|
||||||
|
---@field alpha number?
|
||||||
|
---@field size number?
|
|
@ -0,0 +1,171 @@
|
||||||
|
|
||||||
|
require "common.class"
|
||||||
|
|
||||||
|
require "api.graphics"
|
||||||
|
|
||||||
|
---@class ImageParams
|
||||||
|
---@field width number
|
||||||
|
---@field height number
|
||||||
|
---@field x number?
|
||||||
|
---@field y number?
|
||||||
|
---@field scaleX number?
|
||||||
|
---@field scaleY number?
|
||||||
|
---@field centered boolean?
|
||||||
|
---@field blendOp integer?
|
||||||
|
---@field color number[]?
|
||||||
|
---@field alpha number?
|
||||||
|
---@field stroke StrokeParams?
|
||||||
|
|
||||||
|
---@class Image
|
||||||
|
---@field handle integer
|
||||||
|
---@field width number
|
||||||
|
---@field height number
|
||||||
|
---@field x number?
|
||||||
|
---@field y number?
|
||||||
|
---@field scaleX number?
|
||||||
|
---@field scaleY number?
|
||||||
|
---@field centered boolean?
|
||||||
|
---@field blendOp integer?
|
||||||
|
---@field color number[]?
|
||||||
|
---@field alpha number?
|
||||||
|
---@field stroke StrokeParams?
|
||||||
|
local Image = { };
|
||||||
|
|
||||||
|
---Image constructor
|
||||||
|
---@param imagePath string # The path to the skin image to load
|
||||||
|
---@return Image
|
||||||
|
function Image.new(imagePath, noFallback)
|
||||||
|
local handle = gfx.CreateSkinImage(imagePath or '', 0);
|
||||||
|
if (not handle) then
|
||||||
|
game.Log('Failed to load image "' .. imagePath .. '"', game.LOGGER_ERROR);
|
||||||
|
|
||||||
|
if (noFallback) then return nil; end
|
||||||
|
|
||||||
|
handle = gfx.CreateSkinImage('missing.png', 0);
|
||||||
|
if (not handle) then
|
||||||
|
game.Log('Failed to load fallback image "missing.png"', game.LOGGER_ERROR);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local width, height = 64, 64;
|
||||||
|
if (handle) then
|
||||||
|
width, height = gfx.ImageSize(handle);
|
||||||
|
end
|
||||||
|
|
||||||
|
local instance = {
|
||||||
|
handle = handle,
|
||||||
|
width = width,
|
||||||
|
height = height,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Base(Image, instance);
|
||||||
|
end
|
||||||
|
|
||||||
|
---Set the width and height of this Image.
|
||||||
|
---@param width number
|
||||||
|
---@param height number
|
||||||
|
---@return Image # Returns self for method chaining
|
||||||
|
function Image:setSize(width, height)
|
||||||
|
if (type(width) ~= "number") then width = 0; end
|
||||||
|
if (type(height) ~= "number") then height = 0; end
|
||||||
|
|
||||||
|
self.width = width;
|
||||||
|
self.height = height;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
end
|
||||||
|
|
||||||
|
---Set the stored position for this Image.
|
||||||
|
---If the position of this Image will not change frequently,
|
||||||
|
---using this method allows you to cache the render position
|
||||||
|
---instead of passing it to the render method on each invocation.
|
||||||
|
---@param x number
|
||||||
|
---@param y number
|
||||||
|
---@return Image # Returns self for method chaining
|
||||||
|
function Image:setPosition(x, y)
|
||||||
|
if (type(x) ~= "number") then x = 0; end
|
||||||
|
if (type(y) ~= "number") then y = 0; end
|
||||||
|
|
||||||
|
self.x = x;
|
||||||
|
self.y = y;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
end
|
||||||
|
|
||||||
|
---Renders this Image, applying any of the given ImageParams,
|
||||||
|
---then any of the cached Image fields, then any default values.
|
||||||
|
---@param params? ImageParams
|
||||||
|
function Image:render(params)
|
||||||
|
params = params or { };
|
||||||
|
|
||||||
|
local sx = params.scaleX or self.scaleX or 1;
|
||||||
|
local sy = params.scaleY or self.scaleY or 1;
|
||||||
|
|
||||||
|
local x = params.x or self.x or 0;
|
||||||
|
local y = params.y or self.y or 0;
|
||||||
|
|
||||||
|
local w = (params.width or self.width ) * sx;
|
||||||
|
local h = (params.height or self.height) * sy;
|
||||||
|
|
||||||
|
if (params.centered or self.centered) then
|
||||||
|
x = x - w / 2;
|
||||||
|
y = y - h / 2;
|
||||||
|
end
|
||||||
|
|
||||||
|
local blendOp = params.blendOp or self.blendOp or gfx.BLEND_OP_SOURCE_OVER;
|
||||||
|
|
||||||
|
local r = 255;
|
||||||
|
local g = 255;
|
||||||
|
local b = 255;
|
||||||
|
|
||||||
|
if (params.color) then
|
||||||
|
r = params.color[1];
|
||||||
|
g = params.color[2];
|
||||||
|
b = params.color[3];
|
||||||
|
elseif (self.color) then
|
||||||
|
r = self.color[1];
|
||||||
|
g = self.color[2];
|
||||||
|
b = self.color[3];
|
||||||
|
end
|
||||||
|
|
||||||
|
local a = params.alpha or self.alpha or 1;
|
||||||
|
|
||||||
|
gfx.BeginPath();
|
||||||
|
gfx.GlobalCompositeOperation(blendOp);
|
||||||
|
|
||||||
|
if (not self.handle) then
|
||||||
|
gfx.FillColor(r, g, b, a);
|
||||||
|
gfx.Rect(x, y, w, h);
|
||||||
|
gfx.FillColor(255, 255, 255, 255);
|
||||||
|
else
|
||||||
|
gfx.SetImageTint(r, g, b);
|
||||||
|
gfx.ImageRect(x, y, w, h, self.handle, a, 0);
|
||||||
|
gfx.SetImageTint(255, 255, 255);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (params.stroke or self.stroke) then
|
||||||
|
r = 255;
|
||||||
|
g = 255;
|
||||||
|
b = 255;
|
||||||
|
|
||||||
|
if (params.stroke.color) then
|
||||||
|
r = params.stroke.color[1];
|
||||||
|
g = params.stroke.color[2];
|
||||||
|
b = params.stroke.color[3];
|
||||||
|
elseif (self.stroke and self.stroke.color) then
|
||||||
|
r = self.stroke.color[1];
|
||||||
|
g = self.stroke.color[2];
|
||||||
|
b = self.stroke.color[3];
|
||||||
|
end
|
||||||
|
|
||||||
|
a = params.stroke.alpha or (self.stroke and self.stroke.alpha) or 255;
|
||||||
|
|
||||||
|
local size = params.stroke.size or (self.stroke and self.stroke.size) or 1;
|
||||||
|
|
||||||
|
gfx.StrokeColor(r, g, b, a);
|
||||||
|
gfx.StrokeWidth(size);
|
||||||
|
gfx.Stroke();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Image;
|
|
@ -226,7 +226,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
function result_set()
|
function result_set()
|
||||||
local reqTextWords = common.splitString(result.requirement_text, ' ');
|
local reqTextWords = common.split(result.requirement_text, ' ');
|
||||||
for index, word in ipairs(reqTextWords) do
|
for index, word in ipairs(reqTextWords) do
|
||||||
if string.find(word, '%%') ~= nil then -- %% = %, because % is an escape char
|
if string.find(word, '%%') ~= nil then -- %% = %, because % is an escape char
|
||||||
local percNumber = tonumber(string.gsub(word, '%%', ''), 10)
|
local percNumber = tonumber(string.gsub(word, '%%', ''), 10)
|
||||||
|
|
|
@ -1,160 +1,4 @@
|
||||||
gfx.LoadSkinFont("segoeui.ttf")
|
-- NOTE(local): DO NOT PUT ANYTHING HERE PLEASE THANKS
|
||||||
|
-- IF YOU DO THE GAME WILL IMMEDIATELY CRASH AND IT'S NOT THE BEST
|
||||||
-- Memo class
|
-- THANK YOU HAVE A GOOD LUA
|
||||||
-------------
|
gfx.LoadSkinFont("segoeui.ttf")
|
||||||
Memo = {}
|
|
||||||
Memo.new = function()
|
|
||||||
local this = {
|
|
||||||
cache = {}
|
|
||||||
}
|
|
||||||
setmetatable(this, {__index = Memo})
|
|
||||||
return this
|
|
||||||
end
|
|
||||||
|
|
||||||
Memo.memoize = function(this, key, generator)
|
|
||||||
local value = this.cache[key]
|
|
||||||
if not value then
|
|
||||||
value = generator()
|
|
||||||
this.cache[key] = value
|
|
||||||
end
|
|
||||||
return value
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Image class
|
|
||||||
--------------
|
|
||||||
Image = {
|
|
||||||
ANCHOR_LEFT = 1,
|
|
||||||
ANCHOR_CENTER = 2,
|
|
||||||
ANCHOR_RIGHT = 4,
|
|
||||||
ANCHOR_TOP = 8,
|
|
||||||
ANCHOR_BOTTOM = 16
|
|
||||||
}
|
|
||||||
Image.skin = function(filename, imageFlags)
|
|
||||||
imageFlags = imageFlags or 0
|
|
||||||
local image = gfx.CreateSkinImage(filename, imageFlags)
|
|
||||||
return Image.wrap(image)
|
|
||||||
end
|
|
||||||
Image.wrap = function(image)
|
|
||||||
local this = {
|
|
||||||
image = image
|
|
||||||
}
|
|
||||||
local w, h = gfx.ImageSize(this.image)
|
|
||||||
this.w = w
|
|
||||||
this.h = h
|
|
||||||
setmetatable(this, {__index = Image})
|
|
||||||
return this
|
|
||||||
end
|
|
||||||
|
|
||||||
Image.draw = function(this, params)
|
|
||||||
local x = params.x
|
|
||||||
local y = params.y
|
|
||||||
local w = params.w or this.w
|
|
||||||
local h = params.h or this.h
|
|
||||||
local alpha = params.alpha or 1
|
|
||||||
local angle = params.angle or 0
|
|
||||||
local anchor_h = params.anchor_h or Image.ANCHOR_CENTER
|
|
||||||
local anchor_v = params.anchor_v or Image.ANCHOR_CENTER
|
|
||||||
local scale = params.scale or 1;
|
|
||||||
|
|
||||||
w = w * scale;
|
|
||||||
h = h * scale;
|
|
||||||
|
|
||||||
if anchor_h == Image.ANCHOR_CENTER then
|
|
||||||
x = x - w / 2
|
|
||||||
elseif anchor_h == Image.ANCHOR_RIGHT then
|
|
||||||
x = x - w
|
|
||||||
end
|
|
||||||
|
|
||||||
if anchor_v == Image.ANCHOR_CENTER then
|
|
||||||
y = y - h / 2
|
|
||||||
elseif anchor_v == Image.ANCHOR_BOTTOM then
|
|
||||||
y = y - h
|
|
||||||
end
|
|
||||||
|
|
||||||
gfx.BeginPath()
|
|
||||||
gfx.ImageRect(x, y, w, h, this.image, alpha, angle)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- ImageFont class
|
|
||||||
------------------
|
|
||||||
ImageFont = {}
|
|
||||||
ImageFont.new = function(path, chars)
|
|
||||||
local this = {
|
|
||||||
images = {}
|
|
||||||
}
|
|
||||||
-- load character images
|
|
||||||
for i = 1, chars:len() do
|
|
||||||
local c = chars:sub(i, i)
|
|
||||||
local n = c
|
|
||||||
if c == "." then
|
|
||||||
n = "dot"
|
|
||||||
end
|
|
||||||
local image = Image.skin(string.format("%s/%s.png", path, n), 0)
|
|
||||||
this.images[c] = image
|
|
||||||
end
|
|
||||||
-- use size of first char as font size
|
|
||||||
local w, h = gfx.ImageSize(this.images[chars:sub(1, 1)].image)
|
|
||||||
this.w = w
|
|
||||||
this.h = h
|
|
||||||
|
|
||||||
setmetatable(this, {__index = ImageFont})
|
|
||||||
return this
|
|
||||||
end
|
|
||||||
ImageFont.draw = function(this, text, x, y, alpha, hFlag, vFlag)
|
|
||||||
local totalW = text:len() * this.w
|
|
||||||
|
|
||||||
-- adjust horizontal alignment
|
|
||||||
if hFlag == gfx.TEXT_ALIGN_CENTER then
|
|
||||||
x = x - totalW / 2
|
|
||||||
elseif hFlag == gfx.TEXT_ALIGN_RIGHT then
|
|
||||||
x = x - totalW
|
|
||||||
end
|
|
||||||
|
|
||||||
-- adjust vertical alignment
|
|
||||||
if vFlag == gfx.TEXT_ALIGN_MIDDLE then
|
|
||||||
y = y - this.h / 2
|
|
||||||
elseif vFlag == gfx.TEXT_ALIGN_BOTTOM then
|
|
||||||
y = y - this.h
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, text:len() do
|
|
||||||
local c = text:sub(i, i)
|
|
||||||
local image = this.images[c]
|
|
||||||
if image ~= nil then
|
|
||||||
gfx.BeginPath()
|
|
||||||
gfx.ImageRect(x, y, this.w, this.h, image.image, alpha, 0)
|
|
||||||
end
|
|
||||||
x = x + this.w
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function GetDisplayDifficulty(jacketPath, difficulty)
|
|
||||||
if jacketPath == nil then
|
|
||||||
return difficulty
|
|
||||||
end
|
|
||||||
|
|
||||||
local strippedPath = string.match(jacketPath:lower(), "[/\\][^\\/]+$")
|
|
||||||
if difficulty == 3 and strippedPath then
|
|
||||||
if string.find(strippedPath, "inf") ~= nil then
|
|
||||||
return 5
|
|
||||||
elseif string.find(strippedPath, "grv") ~= nil then
|
|
||||||
return 6
|
|
||||||
elseif string.find(strippedPath, "hvn") ~= nil then
|
|
||||||
return 7
|
|
||||||
elseif string.find(strippedPath, "vvd") ~= nil then
|
|
||||||
return 8
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return difficulty+1
|
|
||||||
end
|
|
||||||
|
|
||||||
function split(s, delimiter)
|
|
||||||
result = {};
|
|
||||||
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
|
|
||||||
table.insert(result, match);
|
|
||||||
end
|
|
||||||
return result;
|
|
||||||
end
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
local Charting = { };
|
||||||
|
|
||||||
|
function Charting.GetDisplayDifficulty(jacketPath, difficulty)
|
||||||
|
if jacketPath == nil then
|
||||||
|
return difficulty
|
||||||
|
end
|
||||||
|
|
||||||
|
local strippedPath = string.match(jacketPath:lower(), "[/\\][^\\/]+$")
|
||||||
|
if difficulty == 3 and strippedPath then
|
||||||
|
if string.find(strippedPath, "inf") ~= nil then
|
||||||
|
return 5
|
||||||
|
elseif string.find(strippedPath, "grv") ~= nil then
|
||||||
|
return 6
|
||||||
|
elseif string.find(strippedPath, "hvn") ~= nil then
|
||||||
|
return 7
|
||||||
|
elseif string.find(strippedPath, "vvd") ~= nil then
|
||||||
|
return 8
|
||||||
|
elseif string.find(strippedPath, "xcd") ~= nil then
|
||||||
|
return 9
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return difficulty + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return Charting;
|
|
@ -42,4 +42,21 @@ dimtable.toViewSpace = function(screenX, screenY, offsetX, offsetY)
|
||||||
return viewX, viewY
|
return viewX, viewY
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Set's up scaled transforms based on the current resolution.
|
||||||
|
---@param x number
|
||||||
|
---@param y number
|
||||||
|
---@param rotation number
|
||||||
|
---@return number, boolean # The scale applied to the transform and the current landscape state
|
||||||
|
function dimtable.setUpTransforms(x, y, rotation)
|
||||||
|
local scale = dimtable.screen.width / dimtable.view.width;
|
||||||
|
local isLandscape = dimtable.view.width > dimtable.view.height;
|
||||||
|
|
||||||
|
gfx.ResetTransform();
|
||||||
|
gfx.Translate(x, y);
|
||||||
|
gfx.Rotate(rotation);
|
||||||
|
gfx.Scale(scale, scale);
|
||||||
|
|
||||||
|
return scale, isLandscape;
|
||||||
|
end
|
||||||
|
|
||||||
return dimtable
|
return dimtable
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
local function splitString(inputstr, sep)
|
local function split(s, delimiter)
|
||||||
if sep == nil then
|
result = {};
|
||||||
sep = "%s"
|
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
|
||||||
|
table.insert(result, match);
|
||||||
end
|
end
|
||||||
local t={}
|
return result;
|
||||||
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
|
|
||||||
table.insert(t, str)
|
|
||||||
end
|
|
||||||
return t
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function filter(tableIn, predicate)
|
local function filter(tableIn, predicate)
|
||||||
|
@ -67,8 +64,19 @@ local function modIndex(index, mod)
|
||||||
return (index - 1) % mod + 1
|
return (index - 1) % mod + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function firstAlphaNum(s)
|
||||||
|
for i = 1, string.len(s) do
|
||||||
|
local byte = string.byte(s, i);
|
||||||
|
if ((byte >= 65 and byte <= 90) or (byte >= 97 and byte <= 122) or (byte >= 48 and byte <= 57)) then
|
||||||
|
return string.sub(s, i, i);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return '';
|
||||||
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
splitString = splitString,
|
split = split,
|
||||||
filter = filter,
|
filter = filter,
|
||||||
clamp = clamp,
|
clamp = clamp,
|
||||||
round = round,
|
round = round,
|
||||||
|
@ -77,4 +85,5 @@ return {
|
||||||
areaOverlap = areaOverlap,
|
areaOverlap = areaOverlap,
|
||||||
lerp = lerp,
|
lerp = lerp,
|
||||||
modIndex = modIndex,
|
modIndex = modIndex,
|
||||||
}
|
firstAlphaNum = firstAlphaNum,
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
local resx, resy = game.GetResolution()
|
local resx, resy = game.GetResolution()
|
||||||
local desw, desh = 1080,1920;
|
local desw, desh = 1080,1920;
|
||||||
local scale = 1;
|
local scale = 1;
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
|
||||||
local VolforceWindow = require('components.volforceWindow')
|
local VolforceWindow = require('components.volforceWindow')
|
||||||
|
local Dimensions = require 'common.dimensions';
|
||||||
|
|
||||||
|
do
|
||||||
|
local resx, resy = game.GetResolution();
|
||||||
|
Dimensions.updateResolution(resx / resy);
|
||||||
|
end
|
||||||
|
|
||||||
local Banner = require('gameplay.banner')
|
local Banner = require('gameplay.banner')
|
||||||
local CritLine = require('gameplay.crit_line')
|
local CritLine = require('gameplay.crit_line')
|
||||||
|
@ -11,31 +17,13 @@ local Gauge = require('gameplay.gauge')
|
||||||
local Chain = require('gameplay.chain')
|
local Chain = require('gameplay.chain')
|
||||||
local LaserAlert = require('gameplay.laser_alert')
|
local LaserAlert = require('gameplay.laser_alert')
|
||||||
|
|
||||||
|
local HitFX = require 'gameplay.hitfx'
|
||||||
|
|
||||||
local TrackEnd = require('gameplay.track_end')
|
local TrackEnd = require('gameplay.track_end')
|
||||||
|
|
||||||
local json = require("common.json")
|
local json = require("common.json")
|
||||||
|
|
||||||
-- Window variables
|
local showHitAnims = true;
|
||||||
local resX, resY
|
|
||||||
|
|
||||||
-- Aspect Ratios
|
|
||||||
local landscapeWidescreenRatio = 16 / 9
|
|
||||||
local landscapeStandardRatio = 4 / 3
|
|
||||||
local portraitWidescreenRatio = 9 / 16
|
|
||||||
|
|
||||||
-- Portrait sizes
|
|
||||||
local fullX, fullY
|
|
||||||
local desw = 1080
|
|
||||||
local desh = 1920
|
|
||||||
|
|
||||||
local resolutionChange = function(x, y)
|
|
||||||
resX = x
|
|
||||||
resY = y
|
|
||||||
fullX = portraitWidescreenRatio * y
|
|
||||||
fullY = y
|
|
||||||
|
|
||||||
game.Log('resX:' .. resX .. ' // resY:' .. resY .. ' // fullX:' .. fullX .. ' // fullY:' .. fullY, game.LOGGER_ERROR);
|
|
||||||
end
|
|
||||||
|
|
||||||
local users = nil
|
local users = nil
|
||||||
|
|
||||||
|
@ -44,11 +32,8 @@ local chain = 0;
|
||||||
local score = 0;
|
local score = 0;
|
||||||
|
|
||||||
function render(deltaTime)
|
function render(deltaTime)
|
||||||
-- detect resolution change
|
|
||||||
local resx, resy = game.GetResolution();
|
local resx, resy = game.GetResolution();
|
||||||
if resx ~= resX or resy ~= resY then
|
Dimensions.updateResolution(resx / resy);
|
||||||
resolutionChange(resx, resy)
|
|
||||||
end
|
|
||||||
|
|
||||||
Banner.render(deltaTime, users, gameplay.user_id);
|
Banner.render(deltaTime, users, gameplay.user_id);
|
||||||
|
|
||||||
|
@ -78,11 +63,11 @@ end
|
||||||
|
|
||||||
function render_crit_base(deltaTime)
|
function render_crit_base(deltaTime)
|
||||||
CritLine.renderBase(deltaTime, gameplay.critLine.x, gameplay.critLine.y, -gameplay.critLine.rotation, gameplay.critLine.cursors);
|
CritLine.renderBase(deltaTime, gameplay.critLine.x, gameplay.critLine.y, -gameplay.critLine.rotation, gameplay.critLine.cursors);
|
||||||
|
HitFX.render(deltaTime, gameplay.critLine.x, gameplay.critLine.y, -gameplay.critLine.rotation, gameplay.critLine.cursors);
|
||||||
Console.render(deltaTime, gameplay.critLine.x, gameplay.critLine.y, -gameplay.critLine.rotation);
|
Console.render(deltaTime, gameplay.critLine.x, gameplay.critLine.y, -gameplay.critLine.rotation);
|
||||||
end
|
end
|
||||||
|
|
||||||
function render_crit_overlay(deltaTime)
|
function render_crit_overlay(deltaTime)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function render_intro(deltaTime)
|
function render_intro(deltaTime)
|
||||||
|
@ -121,11 +106,14 @@ function near_hit(wasLate)
|
||||||
end
|
end
|
||||||
|
|
||||||
function button_hit(button, rating, delta)
|
function button_hit(button, rating, delta)
|
||||||
|
if (showHitAnims) then
|
||||||
|
HitFX.TriggerAnimation("Crit", button + 1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function laser_slam_hit(slamLength, startPos, endPost, index)
|
function laser_slam_hit(slamLength, startPos, endPost, index)
|
||||||
|
if (showHitAnims) then
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function laser_alert(isRight)
|
function laser_alert(isRight)
|
||||||
|
@ -156,9 +144,9 @@ end
|
||||||
|
|
||||||
-- Update the users in the scoreboard
|
-- Update the users in the scoreboard
|
||||||
function score_callback(response)
|
function score_callback(response)
|
||||||
if response.status ~= 200 then
|
if response.status ~= 200 then
|
||||||
error()
|
error()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local jsondata = json.decode(response.text)
|
local jsondata = json.decode(response.text)
|
||||||
users = {}
|
users = {}
|
||||||
|
|
|
@ -1,30 +1,18 @@
|
||||||
|
|
||||||
|
local Dimensions = require 'common.dimensions'
|
||||||
|
|
||||||
local consoleBaseImage = gfx.CreateSkinImage("gameplay/console/base.png", 0)
|
local consoleBaseImage = gfx.CreateSkinImage("gameplay/console/base.png", 0)
|
||||||
|
|
||||||
local CONSOLE_W = 1352;
|
local CONSOLE_W = 1352;
|
||||||
local CONSOLE_H = 712;
|
local CONSOLE_H = 712;
|
||||||
|
|
||||||
-- Similar to crit line transforms, since the console needs to follow the lane rotation
|
|
||||||
local setUpTransforms = function (x,y,rotation)
|
|
||||||
local resx, resy = game.GetResolution()
|
|
||||||
local desw = 1080
|
|
||||||
local desh = 1920
|
|
||||||
local scale = resx / desw
|
|
||||||
|
|
||||||
|
|
||||||
gfx.Translate(x, y)
|
|
||||||
gfx.Rotate(rotation)
|
|
||||||
gfx.Scale(scale,scale)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local render = function (deltaTime, critLineCenterX, critLineCenterY, critLineRotation)
|
local render = function (deltaTime, critLineCenterX, critLineCenterY, critLineRotation)
|
||||||
local resx, resy = game.GetResolution();
|
local resx, resy = game.GetResolution();
|
||||||
if (resx > resy) then
|
if (resx > resy) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
setUpTransforms(
|
Dimensions.setUpTransforms(
|
||||||
critLineCenterX,
|
critLineCenterX,
|
||||||
critLineCenterY,
|
critLineCenterY,
|
||||||
critLineRotation
|
critLineRotation
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
|
|
||||||
|
local Dimensions = require 'common.dimensions'
|
||||||
|
|
||||||
|
local blackGradientImage = gfx.CreateSkinImage('gameplay/crit_line/black_gradient.png', 0)
|
||||||
|
|
||||||
local baseImage = gfx.CreateSkinImage("gameplay/crit_line/base.png", 0)
|
local baseImage = gfx.CreateSkinImage("gameplay/crit_line/base.png", 0)
|
||||||
local baseImageLandscape = gfx.CreateSkinImage("gameplay/crit_line/base_landscape.png", 0)
|
local baseImageLandscape = gfx.CreateSkinImage("gameplay/crit_line/base_landscape.png", 0)
|
||||||
local textImage = gfx.CreateSkinImage("gameplay/crit_line/text.png", 0)
|
local textImage = gfx.CreateSkinImage("gameplay/crit_line/text.png", 0)
|
||||||
|
@ -14,45 +18,26 @@ local cursorGlowTopImages = {
|
||||||
gfx.CreateSkinImage("gameplay/crit_line/cursor_glow_top_right.png", 0),
|
gfx.CreateSkinImage("gameplay/crit_line/cursor_glow_top_right.png", 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
local CRITBAR_W = 1496
|
local CRITBAR_W = 1080
|
||||||
local CRITBAR_H = 348
|
local CRITBAR_H = 251
|
||||||
|
|
||||||
local scale;
|
|
||||||
|
|
||||||
|
local scale = 1;
|
||||||
local isLandscape = false;
|
local isLandscape = false;
|
||||||
|
|
||||||
local setUpTransforms = function (x,y,rotation)
|
|
||||||
local resx, resy = game.GetResolution();
|
|
||||||
isLandscape = resx > resy;
|
|
||||||
|
|
||||||
local desw, desh;
|
|
||||||
|
|
||||||
if (isLandscape) then
|
|
||||||
desw = 1920;
|
|
||||||
desh = 1080;
|
|
||||||
else
|
|
||||||
desw = 1080;
|
|
||||||
desh = 1920;
|
|
||||||
end
|
|
||||||
|
|
||||||
scale = resx / desw
|
|
||||||
|
|
||||||
gfx.Translate(x, y)
|
|
||||||
gfx.Rotate(rotation)
|
|
||||||
gfx.Scale(scale,scale)
|
|
||||||
end
|
|
||||||
|
|
||||||
local drawCursors = function (centerX, centerY,cursors)
|
local drawCursors = function (centerX, centerY,cursors)
|
||||||
local cursorW = 598*0.2;
|
local cursorW = 598 * 0.165;
|
||||||
local cursorH = 673*0.2;
|
local cursorH = 673 * 0.14;
|
||||||
for i = 0, 1, 1 do
|
for i = 0, 1, 1 do
|
||||||
gfx.Save();
|
|
||||||
local cursor = cursors[i];
|
local cursor = cursors[i];
|
||||||
gfx.BeginPath();
|
|
||||||
gfx.SkewX(cursor.skew)
|
|
||||||
|
|
||||||
local cursorX = (cursor.pos *(1/scale) - cursorW/2);
|
gfx.Save();
|
||||||
local cursorY = (-cursorH/2);
|
gfx.BeginPath();
|
||||||
|
|
||||||
|
local skew = cursor.pos * 0.001;
|
||||||
|
gfx.SkewX(skew);
|
||||||
|
|
||||||
|
local cursorX = cursor.pos * (1 / scale) - cursorW / 2;
|
||||||
|
local cursorY = -cursorH / 2;
|
||||||
|
|
||||||
gfx.ImageRect(
|
gfx.ImageRect(
|
||||||
cursorX,
|
cursorX,
|
||||||
|
@ -99,27 +84,28 @@ local drawCursors = function (centerX, centerY,cursors)
|
||||||
end
|
end
|
||||||
|
|
||||||
local renderBase = function (deltaTime, centerX, centerY, rotation, cursors)
|
local renderBase = function (deltaTime, centerX, centerY, rotation, cursors)
|
||||||
setUpTransforms(centerX, centerY, rotation)
|
scale, isLandscape = Dimensions.setUpTransforms(centerX, centerY, rotation)
|
||||||
|
|
||||||
gfx.BeginPath()
|
gfx.BeginPath()
|
||||||
gfx.FillColor(0, 0, 0, 192)
|
gfx.FillColor(0, 0, 0, 192)
|
||||||
gfx.Rect(-1080/2, 0, 1080, 1080)
|
gfx.Rect(-9999, 0, 9999 * 2, 1080)
|
||||||
gfx.Fill()
|
gfx.Fill()
|
||||||
|
|
||||||
gfx.BeginPath();
|
|
||||||
if (isLandscape) then
|
if (isLandscape) then
|
||||||
gfx.ImageRect(-CRITBAR_W/2, -CRITBAR_H/2, CRITBAR_W, CRITBAR_H, baseImageLandscape, 1, 0);
|
gfx.BeginPath();
|
||||||
|
gfx.ImageRect(-9999, -CRITBAR_H/2, 9999 * 2, CRITBAR_H, baseImageLandscape, 1, 0);
|
||||||
else
|
else
|
||||||
|
gfx.BeginPath();
|
||||||
gfx.ImageRect(-CRITBAR_W/2, -CRITBAR_H/2, CRITBAR_W, CRITBAR_H, baseImage, 1, 0);
|
gfx.ImageRect(-CRITBAR_W/2, -CRITBAR_H/2, CRITBAR_W, CRITBAR_H, baseImage, 1, 0);
|
||||||
end
|
end
|
||||||
|
|
||||||
drawCursors(centerX, centerY, cursors)
|
drawCursors(centerX, centerY, cursors)
|
||||||
|
|
||||||
gfx.ResetTransform()
|
gfx.ResetTransform()
|
||||||
end
|
end
|
||||||
|
|
||||||
local renderOverlay = function (deltaTime)
|
local renderOverlay = function (deltaTime)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
|
||||||
|
require 'common.globals'
|
||||||
|
|
||||||
|
local Dimensions = require 'common.dimensions'
|
||||||
|
|
||||||
|
local Animation = require 'api.animation'
|
||||||
|
|
||||||
|
local Animations = {
|
||||||
|
Crit = Animation.new('gameplay/hit_animation_frames/critical_taps', {
|
||||||
|
centered = true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
Near = Animation.new('gameplay/hit_animation_frames/near_taps', {
|
||||||
|
centered = true,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
local animationStates = {
|
||||||
|
---@type AnimationState[]
|
||||||
|
Hold = { },
|
||||||
|
---@type AnimationState[]
|
||||||
|
Tap = { }
|
||||||
|
};
|
||||||
|
|
||||||
|
local HitFX = { };
|
||||||
|
|
||||||
|
local LanePositions = {
|
||||||
|
1.5 / 6,
|
||||||
|
2.5 / 6,
|
||||||
|
3.5 / 6,
|
||||||
|
4.5 / 6,
|
||||||
|
1 / 3,
|
||||||
|
2 / 3
|
||||||
|
};
|
||||||
|
|
||||||
|
local function setupLaneTransform(lanePosition, critCenterX, critCenterY)
|
||||||
|
local critLine = gameplay.critLine;
|
||||||
|
local x = critCenterX + (critLine.line.x2 - critLine.line.x1) * lanePosition;
|
||||||
|
local y = critCenterY + (critLine.line.y2 - critLine.line.y1) * lanePosition;
|
||||||
|
Dimensions.setUpTransforms(x, y, -critLine.rotation);
|
||||||
|
end
|
||||||
|
|
||||||
|
function HitFX.render(deltaTime, critCenterX, critCenterY, critRotation, cursors)
|
||||||
|
local baseHitSize = 325;
|
||||||
|
|
||||||
|
for i = 1, 6 do
|
||||||
|
local hitSize = baseHitSize;
|
||||||
|
if (i > 4) then
|
||||||
|
hitSize = hitSize * 1.5;
|
||||||
|
end
|
||||||
|
|
||||||
|
local laneWidth = (track.GetCurrentLaneXPos(2) - track.GetCurrentLaneXPos(1)) * (i <= 4 and 1 or 2);
|
||||||
|
local lanePosition = track.GetCurrentLaneXPos(i) + laneWidth / 2
|
||||||
|
if (i == 5) then
|
||||||
|
lanePosition = -track.GetCurrentLaneXPos(6) - laneWidth / 2
|
||||||
|
end
|
||||||
|
|
||||||
|
local holdState = animationStates.Hold[i];
|
||||||
|
local tapState = animationStates.Tap[i];
|
||||||
|
|
||||||
|
local isHeld = gameplay.noteHeld[i];
|
||||||
|
if (isHeld) then
|
||||||
|
if (holdState) then
|
||||||
|
if (not holdState.running) then
|
||||||
|
holdState:restart();
|
||||||
|
end
|
||||||
|
|
||||||
|
setupLaneTransform(lanePosition, critCenterX, critCenterY);
|
||||||
|
holdState:render(deltaTime);
|
||||||
|
gfx.ResetTransform();
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (holdState and holdState.running) then
|
||||||
|
holdState:restart();
|
||||||
|
end
|
||||||
|
|
||||||
|
if (tapState and tapState.running) then
|
||||||
|
setupLaneTransform(lanePosition, critCenterX, critCenterY);
|
||||||
|
tapState:render(deltaTime, {
|
||||||
|
centered = true,
|
||||||
|
width = hitSize,
|
||||||
|
height = hitSize,
|
||||||
|
});
|
||||||
|
gfx.ResetTransform();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function HitFX.TriggerAnimation(name, lane)
|
||||||
|
animationStates.Tap[lane] = Animations[name]:start();
|
||||||
|
end
|
||||||
|
|
||||||
|
return HitFX;
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
|
local Charting = require('common.charting');
|
||||||
local DiffRectangle = require('components.diff_rectangle');
|
local DiffRectangle = require('components.diff_rectangle');
|
||||||
|
|
||||||
local desw = 1080;
|
local desw = 1080;
|
||||||
|
@ -98,7 +99,7 @@ local render = function (deltaTime, bpm, laneSpeed, jacketPath, diff, level, pro
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Draw diff rectangle
|
-- Draw diff rectangle
|
||||||
local adjustedDiff = GetDisplayDifficulty(gameplay.jacketPath, diff)
|
local adjustedDiff = Charting.GetDisplayDifficulty(gameplay.jacketPath, diff)
|
||||||
DiffRectangle.render(deltaTime, 31, y+140, 0.84, adjustedDiff, level);
|
DiffRectangle.render(deltaTime, 31, y+140, 0.84, adjustedDiff, level);
|
||||||
|
|
||||||
gfx.FontSize(30);
|
gfx.FontSize(30);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
local Easing = require('common.easing');
|
local Easing = require('common.easing');
|
||||||
|
local Charting = require('common.charting');
|
||||||
local Background = require('components.background');
|
local Background = require('components.background');
|
||||||
local Footer = require('components.footer');
|
local Footer = require('components.footer');
|
||||||
local Numbers = require('components.numbers')
|
local Numbers = require('components.numbers')
|
||||||
|
@ -599,7 +600,7 @@ end
|
||||||
local drawJacketPanelContent = function(deltaTime)
|
local drawJacketPanelContent = function(deltaTime)
|
||||||
gfx.BeginPath();
|
gfx.BeginPath();
|
||||||
gfx.ImageRect(jacketPanelX + 13, jacketPanelY + 28, 265, 265, jacketImage or defaultJacketImage, 1, 0);
|
gfx.ImageRect(jacketPanelX + 13, jacketPanelY + 28, 265, 265, jacketImage or defaultJacketImage, 1, 0);
|
||||||
local adjustedDiff = GetDisplayDifficulty(result.jacketPath, result.difficulty)
|
local adjustedDiff = Charting.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, adjustedDiff, result.level);
|
||||||
|
|
||||||
-- gfx.BeginPath();
|
-- gfx.BeginPath();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
local Common = require("common.util")
|
local Common = require("common.util")
|
||||||
|
local Charting = require('common.charting')
|
||||||
local Numbers = require('components.numbers')
|
local Numbers = require('components.numbers')
|
||||||
local DiffRectangle = require("components.diff_rectangle")
|
local DiffRectangle = require("components.diff_rectangle")
|
||||||
local Header = require("components.headers.challengeSelectHeader")
|
local Header = require("components.headers.challengeSelectHeader")
|
||||||
|
@ -164,7 +165,7 @@ local check_or_create_cache = function(challenge)
|
||||||
|
|
||||||
if not challengeCache[challenge.id]["percent_required"] then
|
if not challengeCache[challenge.id]["percent_required"] then
|
||||||
local percentRequired = 100
|
local percentRequired = 100
|
||||||
local reqTextWords = Common.splitString(challenge.requirement_text, ' ');
|
local reqTextWords = Common.split(challenge.requirement_text, ' ');
|
||||||
for _, word in ipairs(reqTextWords) do
|
for _, word in ipairs(reqTextWords) do
|
||||||
if string.find(word, '%%') ~= nil then -- %% = %, because % is an escape char
|
if string.find(word, '%%') ~= nil then -- %% = %, because % is an escape char
|
||||||
local percentNumber = tonumber(string.gsub(word, '%%', ''), 10)
|
local percentNumber = tonumber(string.gsub(word, '%%', ''), 10)
|
||||||
|
@ -405,7 +406,7 @@ 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)
|
local adjustedDiff = Charting.GetDisplayDifficulty(chart.jacketPath, chart.difficulty)
|
||||||
DiffRectangle.render(timer, offsetX, ypos, diffIconScale, adjustedDiff, chart.level)
|
DiffRectangle.render(timer, offsetX, ypos, diffIconScale, adjustedDiff, chart.level)
|
||||||
|
|
||||||
local _, titleHeight = gfx.LabelSize(chart.title)
|
local _, titleHeight = gfx.LabelSize(chart.title)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
require('common')
|
|
||||||
local Easing = require('common.easing')
|
local Easing = require('common.easing')
|
||||||
local Dim = require("common.dimensions")
|
local Dim = require("common.dimensions")
|
||||||
local SongSelectHeader = require('components.headers.songSelectHeader')
|
local SongSelectHeader = require('components.headers.songSelectHeader')
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
require('common')
|
local Charting = require('common.charting')
|
||||||
local Easing = require('common.easing')
|
local Easing = require('common.easing')
|
||||||
local Background = require('components.background')
|
local Background = require('components.background')
|
||||||
local Dim = require("common.dimensions")
|
local Dim = require("common.dimensions")
|
||||||
|
@ -328,7 +328,7 @@ function drawSong(song, y)
|
||||||
|
|
||||||
-- Draw the difficulty notch background
|
-- Draw the difficulty notch background
|
||||||
gfx.BeginPath()
|
gfx.BeginPath()
|
||||||
local diffIndex = GetDisplayDifficulty(selectedSongDifficulty.jacketPath, selectedSongDifficulty.difficulty)
|
local diffIndex = Charting.GetDisplayDifficulty(selectedSongDifficulty.jacketPath, selectedSongDifficulty.difficulty)
|
||||||
gfx.ImageRect(songX, y+95, 83, 74, difficultyLabelImages[diffIndex], 1, 0)
|
gfx.ImageRect(songX, y+95, 83, 74, difficultyLabelImages[diffIndex], 1, 0)
|
||||||
|
|
||||||
-- Draw the difficulty level number
|
-- Draw the difficulty level number
|
||||||
|
@ -498,7 +498,7 @@ function drawData() -- Draws the song data on the left panel
|
||||||
Numbers.draw_number(85+(index-1)*DIFF_GAP, 1085, 1.0, diff.level, 2, difficultyNumbers, false, 0.8, 1)
|
Numbers.draw_number(85+(index-1)*DIFF_GAP, 1085, 1.0, diff.level, 2, difficultyNumbers, false, 0.8, 1)
|
||||||
|
|
||||||
local diffLabelImage = difficultyLabelUnderImages[
|
local diffLabelImage = difficultyLabelUnderImages[
|
||||||
GetDisplayDifficulty(diff.jacketPath, diff.difficulty)
|
Charting.GetDisplayDifficulty(diff.jacketPath, diff.difficulty)
|
||||||
]
|
]
|
||||||
local tw, th = gfx.ImageSize(diffLabelImage)
|
local tw, th = gfx.ImageSize(diffLabelImage)
|
||||||
tw=tw*0.9
|
tw=tw*0.9
|
||||||
|
@ -785,8 +785,9 @@ function drawScrollbar()
|
||||||
gfx.FillColor(255,255,255)
|
gfx.FillColor(255,255,255)
|
||||||
gfx.TextAlign(gfx.TEXT_ALIGN_MIDDLE + gfx.TEXT_ALIGN_CENTER)
|
gfx.TextAlign(gfx.TEXT_ALIGN_MIDDLE + gfx.TEXT_ALIGN_CENTER)
|
||||||
if (songwheel.songs[selectedIndex] ~= nil) then
|
if (songwheel.songs[selectedIndex] ~= nil) then
|
||||||
local letter = string.upper(common.firstLetter(songwheel.songs[selectedIndex].title))
|
local title = songwheel.songs[selectedIndex].title;
|
||||||
gfx.Text(letter, fillXPos-10, scrollbarYPos + 5)
|
local letter = string.upper(common.firstAlphaNum(title))
|
||||||
|
gfx.Text(letter, fillXPos-10, scrollbarYPos + 5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
require('common')
|
|
||||||
local Easing = require('common.easing');
|
local Easing = require('common.easing');
|
||||||
|
|
||||||
local resx, resy = game.GetResolution()
|
local resx, resy = game.GetResolution()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
require("common")
|
|
||||||
local Footer = require("components.footer")
|
local Footer = require("components.footer")
|
||||||
local Wallpaper = require("components.wallpaper")
|
local Wallpaper = require("components.wallpaper")
|
||||||
local Background = require("components.background")
|
local Background = require("components.background")
|
||||||
|
|
After Width: | Height: | Size: 785 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 91 B After Width: | Height: | Size: 133 B |
After Width: | Height: | Size: 226 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 194 B |