diff --git a/src/love/.vscode/settings.json b/src/love/.vscode/settings.json index a6c69c9d..5a1fcc13 100644 --- a/src/love/.vscode/settings.json +++ b/src/love/.vscode/settings.json @@ -3,7 +3,8 @@ "love" ], "Lua.diagnostics.disable": [ - "redundant-parameter" + "redundant-parameter", + "missing-parameter" ], "Lua.runtime.version": "LuaJIT", "Lua.runtime.special": [], diff --git a/src/love/images/dds/resultsScreen/resultSuperFuckingMarioGOOD.dds b/src/love/images/dds/resultsScreen/resultSuperFuckingMarioGOOD.dds new file mode 100644 index 00000000..fead72ef Binary files /dev/null and b/src/love/images/dds/resultsScreen/resultSuperFuckingMarioGOOD.dds differ diff --git a/src/love/images/png/menu/menu_mods.png b/src/love/images/png/menu/menu_mods.png new file mode 100644 index 00000000..327680d5 Binary files /dev/null and b/src/love/images/png/menu/menu_mods.png differ diff --git a/src/love/lib/fft/luafft.lua b/src/love/lib/fft/luafft.lua index 3478ffa2..ed946d82 100644 --- a/src/love/lib/fft/luafft.lua +++ b/src/love/lib/fft/luafft.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: undefined-global --[[ This package provides functions to carry out Fast Fourier Transformations. diff --git a/src/love/main.lua b/src/love/main.lua index 807ee3db..81341ec4 100644 --- a/src/love/main.lua +++ b/src/love/main.lua @@ -269,6 +269,7 @@ function love.load() menuSettings = require "states.menu.options.OptionsState" menuCredits = require "states.menu.menuCredits" menuSelect = require "states.menu.menuSelect" + menuMods = require "states.menu.menuMods" resultsScreen = require "states.menu.results" firstStartup = true @@ -616,6 +617,10 @@ function love.mousemoved(x, y, dx, dy, istouch) end end +function love.wheelmoved(x, y) + Gamestate.wheelmoved(x, y) +end + function love.touchpressed(id, x, y, dx, dy, pressure) Gamestate.touchpressed(id, x, y, dx, dy, pressure) end diff --git a/src/love/modding/importMods.lua b/src/love/modding/importMods.lua index 9e18342c..7f0042ea 100644 --- a/src/love/modding/importMods.lua +++ b/src/love/modding/importMods.lua @@ -1,6 +1,7 @@ local importMods = {} importMods.storedMods = {} importMods.storedModsScripts = {} +importMods.storedModsIncludingDisabled = {} importMods.inMod = false importMods.uiHealthbarMod = nil importMods.uiHealthbarTextMod = nil @@ -77,6 +78,17 @@ function importMods.loadMod(mod) -- The file name of the mod }) end +function importMods.loadModToAllModsIncludingDisabled(modMeta, path) + table.insert(importMods.storedModsIncludingDisabled, { + name = modMeta.name, + description = modMeta.description, + enabled = modMeta.enabled, + creator = modMeta.creator, + path = path + }) +end + + function importMods.getAllModsStages() local stagesList = {} for i, mod in ipairs(importMods.storedMods) do @@ -93,6 +105,18 @@ function importMods.getAllModsStages() return stagesList end +function importMods.getAllMods() + local modsList = {} + for i, mod in ipairs(importMods.storedModsIncludingDisabled) do + table.insert(modsList, mod) + end + return modsList +end + +function importMods.getModFromIndex(index) + return importMods.storedModsIncludingDisabled[index] +end + function importMods.getStageFileFromName(name) for i, mod in ipairs(importMods.storedMods) do if love.filesystem.getInfo(mod.path .. "/stages/" .. name .. ".lua") then @@ -167,8 +191,10 @@ function importMods.loadAllMods() if love.filesystem.getInfo("mods/" .. mod .. "/meta.lua") then local meta = love.filesystem.load("mods/" .. mod .. "/meta.lua")() if meta.enabled == nil or meta.enabled then + print("Loading mod: " .. mod) importMods.loadMod(mod) end + importMods.loadModToAllModsIncludingDisabled(meta, "mods/" .. mod) end end end @@ -196,6 +222,37 @@ function importMods.getModFromStage(fileName) return nil end +function importMods.rewriteAllMetas(newModMetas) + for i, mod in ipairs(importMods.storedModsIncludingDisabled) do + mod.name = newModMetas[i].name + mod.description = newModMetas[i].description + mod.enabled = newModMetas[i].enabled + mod.creator = newModMetas[i].creator + + love.filesystem.write(mod.path .. "/meta.lua", [[ +return { + enabled = ]] .. tostring(mod.enabled) .. [[, + name = "]] .. mod.name .. [[", + creator = "]] .. mod.creator .. [[", + description = "]] .. mod.description .. [[" +} + ]]) + end +end + +function importMods.reloadAllMods() + importMods.storedMods = {} + importMods.storedModsScripts = {} + importMods.storedModsIncludingDisabled = {} + -- update weekMeta, weekDesc, and weekData to remove all mods past modWeekPlacement + for i = #weekMeta, modWeekPlacement + 1, -1 do + table.remove(weekMeta, i) + table.remove(weekDesc, i) + table.remove(weekData, i) + end + importMods.loadAllMods() +end + function loadLuaFile(path) local currentMod = importMods.getCurrentMod() diff --git a/src/love/modules/graphics.lua b/src/love/modules/graphics.lua index 8981633b..5ab32bda 100644 --- a/src/love/modules/graphics.lua +++ b/src/love/modules/graphics.lua @@ -35,10 +35,10 @@ return { screenWidth, screenHeight = width, height end, getWidth = function() - return screenWidth or love.graphics.getWidth() + return 1280 or love.graphics.getWidth() end, getHeight = function() - return screenHeight or love.graphics.getHeight() + return 720 or love.graphics.getHeight() end, cache = {}, diff --git a/src/love/sprites/Alphabet.lua b/src/love/sprites/Alphabet.lua index e042babc..50764c66 100644 --- a/src/love/sprites/Alphabet.lua +++ b/src/love/sprites/Alphabet.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: undefined-global return graphics.newSprite( Alphabet.image, -- Automatically generated from alphabet.xml diff --git a/src/love/sprites/menu/mods.lua b/src/love/sprites/menu/mods.lua new file mode 100644 index 00000000..7c209cc5 --- /dev/null +++ b/src/love/sprites/menu/mods.lua @@ -0,0 +1,24 @@ +return graphics.newSprite( + love.graphics.newImage(graphics.imagePath("menu/menu_mods")), + -- Automatically generated from menu_mods.xml + { + {x = 0, y = 0, width = 355, height = 139, offsetX = 0, offsetY = -1, offsetWidth = 355, offsetHeight = 140, rotated = false}, -- 1: mods basic0000 + {x = 0, y = 0, width = 355, height = 139, offsetX = 0, offsetY = -1, offsetWidth = 355, offsetHeight = 140, rotated = false}, -- 2: mods basic0001 + {x = 0, y = 0, width = 355, height = 139, offsetX = 0, offsetY = -1, offsetWidth = 355, offsetHeight = 140, rotated = false}, -- 3: mods basic0002 + {x = 356, y = 0, width = 355, height = 140, offsetX = 0, offsetY = 0, offsetWidth = 0, offsetHeight = 0, rotated = false}, -- 4: mods basic0003 + {x = 356, y = 0, width = 355, height = 140, offsetX = 0, offsetY = 0, offsetWidth = 0, offsetHeight = 0, rotated = false}, -- 5: mods basic0004 + {x = 356, y = 0, width = 355, height = 140, offsetX = 0, offsetY = 0, offsetWidth = 0, offsetHeight = 0, rotated = false}, -- 6: mods basic0005 + {x = 0, y = 141, width = 353, height = 139, offsetX = -1, offsetY = -1, offsetWidth = 355, offsetHeight = 140, rotated = false}, -- 7: mods basic0006 + {x = 0, y = 141, width = 353, height = 139, offsetX = -1, offsetY = -1, offsetWidth = 355, offsetHeight = 140, rotated = false}, -- 8: mods basic0007 + {x = 0, y = 141, width = 353, height = 139, offsetX = -1, offsetY = -1, offsetWidth = 355, offsetHeight = 140, rotated = false}, -- 9: mods basic0008 + {x = 354, y = 141, width = 395, height = 192, offsetX = 0, offsetY = -1, offsetWidth = 401, offsetHeight = 193, rotated = false}, -- 10: mods white0000 + {x = 0, y = 334, width = 401, height = 189, offsetX = 0, offsetY = 0, offsetWidth = 401, offsetHeight = 193, rotated = false}, -- 11: mods white0001 + {x = 402, y = 334, width = 400, height = 189, offsetX = 0, offsetY = -1, offsetWidth = 401, offsetHeight = 193, rotated = false} -- 12: mods white0002 + }, + { + ["hover"] = {start = 10, stop = 12, speed = 24, offsetX = 0, offsetY = 0}, + ["idle"] = {start = 1, stop = 9, speed = 24, offsetX = 0, offsetY = 0} + }, + "idle", + true +) \ No newline at end of file diff --git a/src/love/states/menu/menuMods.lua b/src/love/states/menu/menuMods.lua new file mode 100644 index 00000000..238eda9e --- /dev/null +++ b/src/love/states/menu/menuMods.lua @@ -0,0 +1,290 @@ +local storedModList = {} +local translate = {x = 0, y = 0} +local toTranslate = {x = 0, y = 0} +return { + enter = function(self) + modList = {} + storedModList = {} + + for i = 1, #importMods.getAllMods() do + table.insert(modList, importMods.getModFromIndex(i)) + end + + for i = 1, #modList do + local mod = modList[i] + local icon = mod.path .. "/icon.png" + if not love.filesystem.getInfo(icon) then + icon = "assets/defaultIcon.png" + if not love.filesystem.getInfo(icon) then + icon = nil + end + end + table.insert(storedModList, { + name = mod.name, + icon = icon ~= nil and graphics.newImage(icon) or nil, + description = mod.description, + creator = mod.creator, + hovered = false, + selected = false, + enabled = mod.enabled, + x = -graphics.getWidth() / 2 + 10, + y = -graphics.getHeight() / 2 + 10 + ((i-1) * 85), + width = graphics.getWidth()/4 - 15, + height = 80 + }) + if storedModList[#storedModList].icon then + local icon = storedModList[#storedModList].icon + icon.x, icon.y = -graphics.getWidth() / 2 + 50, -graphics.getHeight() / 2 + 50 + ((i-1) * 85) + icon.sizeX, icon.sizeY = 0.5, 0.5 + end + end + + if #storedModList > 0 then + storedModList[1].selected = true + end + graphics:fadeInWipe(0.6) + end, + + update = function(self, dt) + translate.x = util.coolLerp(translate.x, toTranslate.x, 0.1) + translate.y = util.coolLerp(translate.y, toTranslate.y, 0.1) + + if input:pressed("back") then + graphics:fadeOutWipe(0.6, function() + Gamestate.switch(menuSelect) + end) + end + + if input:pressed("down") then + for i = 1, #storedModList do + if storedModList[i].selected then + storedModList[i].selected = false + if i == #storedModList then + storedModList[1].selected = true + else + storedModList[i+1].selected = true + end + break + end + end + + if #storedModList * 85 > graphics.getHeight() then + for i = 1, #storedModList do + if storedModList[i].selected then + if i == #storedModList then + toTranslate.y = -((#storedModList * 85) - graphics.getHeight()) + elseif i == 1 then + toTranslate.y = 0 + elseif storedModList[i].y - 85 < -graphics.getHeight() / 2 then + toTranslate.y = toTranslate.y - 85 + end + break + end + end + end + elseif input:pressed("up") then + for i = 1, #storedModList do + if storedModList[i].selected then + storedModList[i].selected = false + if i == 1 then + storedModList[#storedModList].selected = true + else + storedModList[i-1].selected = true + end + break + end + end + + if #storedModList * 85 > graphics.getHeight() then + for i = 1, #storedModList do + if storedModList[i].selected then + if i == #storedModList then + toTranslate.y = -((#storedModList * 85) - graphics.getHeight()) + elseif i == 1 then + toTranslate.y = 0 + elseif storedModList[i].y - 85 < -graphics.getHeight() / 2 then + toTranslate.y = toTranslate.y + 85 + end + break + end + end + end + end + + if input:pressed("confirm") then + for i = 1, #storedModList do + if storedModList[i].selected then + storedModList[i].enabled = not storedModList[i].enabled + break + end + end + end + end, + + mousemoved = function(self, x, y, dx, dy, istouch) + local x, y = push.toGame(x, y) + if type(x) == "boolean" or type(y) == "boolean" then return end + x, y = x - graphics.getWidth() / 2, y - graphics.getHeight() / 2 + + for i = 1, #storedModList do + local mod = storedModList[i] + local nx, ny = x - translate.x, y - translate.y + + if nx > mod.x and nx < mod.x + mod.width and ny > mod.y and ny < mod.y + mod.height then + mod.hovered = true + else + mod.hovered = false + end + end + end, + + mousepressed = function(self, x, y, button, istouch, presses) + local x, y = push.toGame(x, y) + if type(x) == "boolean" or type(y) == "boolean" then return end + x, y = x - graphics.getWidth() / 2, y - graphics.getHeight() / 2 + + for i = 1, #storedModList do + local mod = storedModList[i] + local nx, ny = x - translate.x, y - translate.y + + if nx > mod.x and nx < mod.x + mod.width and ny > mod.y and ny < mod.y + mod.height then + for i = 1, #storedModList do + storedModList[i].selected = false + end + mod.selected = true + end + end + + -- enable/disable button + local quartWidth = graphics.getWidth() / 4 + local width = quartWidth * 3 + if x > -quartWidth and x < quartWidth*2 and y > graphics.getHeight() / 2 - 50 and y < graphics.getHeight() / 2 - 10 then + for i = 1, #storedModList do + if storedModList[i].selected then + storedModList[i].enabled = not storedModList[i].enabled + break + end + end + end + --[[ if x > -graphics.getWidth() / 2 and x < -graphics.getWidth() / 2 + graphics.getWidth()/4 and y > graphics.getHeight() / 2 - 50 and y < graphics.getHeight() / 2 - 10 then + for i = 1, #storedModList do + if storedModList[i].selected then + storedModList[i].enabled = not storedModList[i].enabled + break + end + end + end ]] + end, + + wheelmoved = function(self, x, y) + toTranslate.y = toTranslate.y + y * 25 + if toTranslate.y > 0 then + toTranslate.y = 0 + else + if #storedModList * 85 < graphics.getHeight() then + toTranslate.y = 0 + elseif toTranslate.y < -((#storedModList * 85) - graphics.getHeight()) then + toTranslate.y = -((#storedModList * 85) - graphics.getHeight()) + end + end + end, + + draw = function(self) + love.graphics.push() + love.graphics.translate(graphics.getWidth() / 2, graphics.getHeight() / 2) + + --[[ for i = 1, #storedModList do + local mod = storedModList[i] + if mod.icon then + mod.icon:draw() + end + love.graphics.print(mod.name, -graphics.getWidth() / 2 + 100, -graphics.getHeight() / 2 + 50 + (i * 100)) + love.graphics.print(mod.description, -graphics.getWidth() / 2 + 100, -graphics.getHeight() / 2 + 50 + (i * 100) + 20) + end ]] + + love.graphics.push() + love.graphics.translate(translate.x, translate.y) + for i = 1, #storedModList do + local mod = storedModList[i] + + -- 0.1 colour if not selected or hovered + -- 0.2 colour if hovered + -- 0.3 colour if selected + if mod.selected then + graphics.setColor(0.3, 0.3, 0.3, 1) + elseif mod.hovered then + graphics.setColor(0.2, 0.2, 0.2, 1) + else + graphics.setColor(0.1, 0.1, 0.1, 1) + end + + love.graphics.rectangle("fill", mod.x, mod.y, mod.width, mod.height) + graphics.setColor(0.8, 0.8, 0.8, 1) + love.graphics.rectangle("line", mod.x, mod.y, mod.width, mod.height) + graphics.setColor(1, 1, 1, 1) + if mod.icon then + mod.icon:draw() + end + + local modName = mod.name + if font:getWidth(modName) > graphics.getWidth()/4 - 20 then + -- replace all chars past the width with ... + local newModName = "" + for i = 1, #modName do + newModName = newModName .. modName:sub(i, i) + if font:getWidth(newModName) > graphics.getWidth()/4 - 15 - font:getWidth("...") then + newModName = newModName .. "..." + break + end + end + + modName = newModName + end + + -- graphics.getWidth()/4 is 1/4 of the screen width + love.graphics.printf(modName, -graphics.getWidth() / 2 + 90, -graphics.getHeight() / 2 + 15 + ((i-1) * 85), graphics.getWidth()/4 - 50, "left") + + if mod.selected then + love.graphics.push() + local quartWidth = graphics.getWidth() / 4 + love.graphics.translate(quartWidth, 0) + + local width = quartWidth * 3 + love.graphics.printf(mod.name, -width / 2-150, -graphics.getHeight() / 2 + 15, width-15, "center") + love.graphics.setLineWidth(2) + love.graphics.line(-width / 2-150, -graphics.getHeight() / 2 + 65, width / 2-150, -graphics.getHeight() / 2 + 65) + love.graphics.setLineWidth(1) + -- left align stuff now + love.graphics.printf("Created by: " .. mod.creator, -width / 2-150, -graphics.getHeight() / 2 + 75, width-15, "left") + love.graphics.printf(mod.description, -width / 2-150, -graphics.getHeight() / 2 + 125, width-15, "left") + + --[[ love.graphics.printf(mod.description, -width / 2-150, -graphics.getHeight() / 2 + 35, width-15, "center") + love.graphics.printf("Created by: " .. mod.creator, -width / 2-150, -graphics.getHeight() / 2 + 55, width-15, "center") ]] + + -- enable/disable button + if mod.enabled then + graphics.setColor(0, 1, 0, 1) + else + graphics.setColor(1, 0, 0, 1) + end + love.graphics.rectangle("fill", -width / 2-150, graphics.getHeight() / 2 - 50, width-15, 40, 15, 15) + graphics.setColor(1, 1, 1, 1) + love.graphics.printf(mod.enabled and "Disable" or "Enable", -width / 2-150, graphics.getHeight() / 2 - 45, width-15, "center") + love.graphics.pop() + end + end + love.graphics.pop() + + love.graphics.setLineWidth(5) + love.graphics.rectangle("line", -graphics.getWidth() / 2, -graphics.getHeight() / 2, graphics.getWidth()/4+5, graphics.getHeight()) + love.graphics.rectangle("line", -graphics.getWidth() / 2, -graphics.getHeight() / 2, graphics.getWidth(), graphics.getHeight()) + love.graphics.setLineWidth(1) + love.graphics.pop() + end, + + leave = function() + importMods.rewriteAllMetas(storedModList) + + importMods.reloadAllMods() + end +} \ No newline at end of file diff --git a/src/love/states/menu/menuSelect.lua b/src/love/states/menu/menuSelect.lua index 2f03e35f..2ca9a7a9 100644 --- a/src/love/states/menu/menuSelect.lua +++ b/src/love/states/menu/menuSelect.lua @@ -49,6 +49,19 @@ return { ) end }, + { + sprite = love.filesystem.load("sprites/menu/mods.lua")(), + confirm = function() + status.setLoading(true) + graphics:fadeOutWipe( + 0.7, + function() + Gamestate.switch(menuMods) + status.setLoading(false) + end + ) + end + }, { sprite = love.filesystem.load("sprites/menu/options.lua")(), confirm = function() @@ -89,7 +102,6 @@ return { button.sprite.sizeY = 0.75 button.sprite.y = -200 + (i - 1) * 100 - print(button.sprite.y) Timer.tween(1, button.sprite, {x = -295 - (i - 1) * 25}, "out-expo") end