local curIndex = 1 return function() local state = {} local dataFolder = love.filesystem.getSaveDirectory() local files = require("modules.files") local json = require("modules.json") local logging = require("modules.logging") local charValues = require("playableCharValues.playables") local playables = charValues.playables local playableOffsets = charValues.offsets local playableFlips = charValues.flips curChar = playables[1] --this needs to be global local curCharIndex = 1 local songs = require(string.format("charts.songs-%s", curChar)) local unparsedData = files.read_file(dataFolder .. "/Data.json") local data = unparsedData and json.parse(unparsedData) or { songs = { bf = {} } } print(unparsedData, data) local chardata = json.parse(files.read_file(string.format("resultScreens/%s.json", curChar))) local animationAliases = {} local animationPositions = {} for index, anim in next, chardata.freeplayDJ.animations do animationAliases[anim.name] = anim.prefix animationPositions[anim.prefix] = Vector2(anim.offsets[1], anim.offsets[2]) end local icons = {} local capsules = {} local function setupIcons() for index, icon in next, icons do icon:Destroy() end for index, capsule in next, capsules do capsule:Destroy() end for index, song in next, songs do local icon = song.icon if not icon then goto evilgoto end local spriteicon = Sprite(string.format("sprites/freeplay/icons/%s.png", icon), string.format("sprites/freeplay/icons/%s.json", icon)) spriteicon:PlayAnimation("idle", .005, false) spriteicon.frame = 1 spriteicon.layer = 10 for index, anim in next, spriteicon.quads do for index, quad in next, anim do quad.resize = Vector2(1.5,1.5) end end local capsule = Sprite(string.format("images/freeplay/freeplayCapsule/capsule/freeplayCapsule_%s.png", curChar), string.format("images/freeplay/freeplayCapsule/capsule/freeplayCapsule_%s.json", curChar)) capsule.position = Vector2() capsule.layer = 5 capsule:PlayAnimation("mp3 capsule w backing NOT SELECTED", 24, true) -- for index, anim in next, capsule.quads do -- for index, quad in next, anim do -- quad.resize = Vector2(0.8,0.8) -- quad.offset = Vector2(quad.offset.x * 0.8, quad.offset.y * 0.8) -- end -- end capsules[song.name] = capsule icons[song.name] = spriteicon ::evilgoto:: end end local flip = false local lastChange = 0 local startedPlaying = 0 local start = false local curSong = songs[1] local evilCurIndex = 1 local curDiffList = songs[1].difficulties local bfAtlas = love.animate.newTextureAtlas() local picoAtlas local curDiff = songs[1].difficulties[1] local curDiffInd = 1 local diffIMG local iconNum = math.random(1, 3) local curState = nil local stateLoaded = false local pressed = { false, false, false } local bg local logo local gf local charSwapSND = love.audio.newSource("sounds/CS_select.ogg", "stream") charSwapSND:setVolume(0.25) local left local arrow local function setup() love.window.setTitle("TaggedEngine: Freeplay") if not freaky:isPlaying() then freaky:play() end start = false bg = Image("images/freeplay/freeplayBGweek1-bf.png", 0) bg.ui = false bg.layer = -10 bg.resize = Vector2(2,2) -- NO MORE GF left = Image("images/freeplay/yellow bg piece.png") left.layer = -5 arrow = Sprite( string.format("sprites/freeplay/freeplaySelector-%s.png", curChar), string.format("sprites/freeplay/freeplaySelector-%s.json", curChar) ) arrow.position.y = 0 arrow.position.x = 0 arrow.layer = 1 arrow.resize = Vector2(.5, .5) arrow.flipX = false arrow:PlayAnimation("arrow pointer loop", 24, true) local arrow2 = Sprite( string.format("sprites/freeplay/freeplaySelector-%s.png", curChar), string.format("sprites/freeplay/freeplaySelector-%s.json", curChar) ) arrow2.position.y = 0 arrow2.position.x = 310 arrow2.layer = 50 arrow2.flipX = true arrow2:PlayAnimation("arrow pointer loop", 24, true) -- render.preLoad( -- "sprites/freeplay/freeplaySelector_pico.png", -- "sprites/freeplay/freeplaySelector.json" -- ) diffIMG = Sprite("images/diff/diffList.png", "images/diff/diffList.json") --look there was a different plan going in diffIMG:PlayAnimation(curDiff, 24, false) diffIMG.position = Vector2(50, 10) diffIMG.layer = 2 bfAtlas = love.animate.newTextureAtlas() bfAtlas:load(string.format("sprites/freeplay/freeplay-%s", curChar)) bfAtlas.looping = false bfAtlas:play(animationAliases.intro) setupIcons() end local function run() if curDiff == "erect" or curDiff == "nightmare" then Erect = "erect" -- I fucking hate fnf devs for this end gameMode = "freeplaymode" render.destroyAllSprites() freaky:stop() state.changeState("playstate", curSong.name, curDiff, true) end local font = love.graphics.newFont("fonts/FridayNightFunkin-Regular.ttf", 40) local smallerFont = love.graphics.newFont("fonts/FridayNightFunkin-Regular.ttf", 20) local scroll = love.audio.newSource("sounds/ui/scrollMenu.ogg", "static") local confirm = love.audio.newSource("sounds/ui/confirmMenu.ogg", "static") function state.update(dt) if start then startedPlaying = startedPlaying + dt if startedPlaying > .5 then run() end end bfAtlas:update(dt) if bfAtlas.libraries and bfAtlas.frame >= bfAtlas:getTimelineLength(bfAtlas:getSymbolTimeline(bfAtlas.symbol)) then bfAtlas:play(animationAliases.idle) end render.cameraPosition = Vector2(0, 0) render.updateSprites(dt) end function state.draw() love.graphics.setDefaultFilter("nearest", "nearest") render.drawSprites() evilCurIndex = Lerp(evilCurIndex, curIndex, .3) for index, song in next, songs do local color = index == curIndex and { 0, 1, 0.8 } or { 0, 1, 1 } love.graphics.print({ color, song.name }, font, 700 - (50 * math.abs(index - evilCurIndex)), love.graphics:getHeight() / 2 + (200 * (index - evilCurIndex - .5)), 0, 1, 1, 200) local icon = icons[song.name] if icon then icon.position = Vector2(450 - (50 * math.abs(index - evilCurIndex)), love.graphics:getHeight() / 2 + (200 * (index - evilCurIndex - .5))) end local capsule = capsules[song.name] capsule.position = Vector2(400 - (50 * math.abs(index - evilCurIndex)), love.graphics:getHeight() / 2 + (200 * (index - evilCurIndex - .5) - 25)) end bfAtlas:draw(animationPositions[bfAtlas.symbol].x, animationPositions[bfAtlas.symbol].y, 0, 1, 1) -- if bfAtlas.symbol == curChar .. " slide in" then -- bfAtlas:draw(curChar == "bf" and 695 or 690, curChar == "bf" and 315 or 320, 0, flip and -1 or 1, 1) -- else -- bfAtlas:draw(curChar == "bf" and 700 or 1150, curChar == "bf" and 300 or 190, 0, flip and -1 or 1, 1) -- end if data.songs[curChar] and data.songs[curChar][curSong.name] and data.songs[curChar][curSong.name][curDiff] then local text = string.format("Accuracy: %s, Score: %s, Rank: %s", tostring(data.songs[curChar][curSong.name][curDiff].accuracy):sub(1, 5), data.songs[curChar][curSong.name][curDiff].score, data.songs[curChar][curSong.name][curDiff].rank) love.graphics.print({ { 0, 0, 0 }, text }, smallerFont, 1280 - text:len() * 10, 0) end end function state.keypressed(key, un, is) if key == "return" then start = true startedPlaying = 0 icons[curSong.name]:PlayAnimation("confirm", 24, false) confirm:stop() confirm:play() bfAtlas:play(animationAliases.confirm) elseif key == "down" then curIndex, curSong = next(songs, curIndex) if not curSong then curIndex, curSong = next(songs) curDiffList = curSong.difficulties else curDiffList = curSong.difficulties end curDiffInd = 1 curDiff = curDiffList[1] diffIMG:PlayAnimation(curDiff, 24, true) scroll:stop() scroll:play() elseif key == "up" then --the solution was so stupid easy if songs[curIndex - 1] then curSong = songs[curIndex - 1] curDiffList = songs[curIndex - 1].difficulties curDiffInd = 1 curDiff = curDiffList[curDiffInd] curIndex = curIndex - 1 else curSong = songs[#songs] curIndex = #songs curDiffList = songs[curIndex].difficulties curDiffInd = 1 curDiff = curDiffList[curDiffInd] end curDiffInd = 1 curDiff = curDiffList[1] diffIMG:PlayAnimation(curDiff, 24, true) scroll:stop() scroll:play() elseif key == "right" then if curDiffList[curDiffInd + 1] then curDiff = curDiffList[curDiffInd + 1] curDiffInd = curDiffInd + 1 else curDiff = curDiffList[1] curDiffInd = 1 end diffIMG:PlayAnimation(curDiff, 24, true) scroll:stop() scroll:play() elseif key == "left" then if curDiffList[curDiffInd - 1] then curDiff = curDiffList[curDiffInd - 1] curDiffInd = curDiffInd - 1 else curDiff = curDiffList[#curDiffList] curDiffInd = #curDiffList end diffIMG:PlayAnimation(curDiff, 24, true) scroll:stop() scroll:play() elseif key == "p" then --changes character to/from pico hopefully arrow:Destroy() -- flip = true curCharIndex, curChar = next(playables, curCharIndex) if not curCharIndex then curCharIndex = 1 curChar = playables[1] end songs = require(string.format("charts.songs-%s", curChar)) --change which catalogue is available json.parse(files.read_file(string.format("resultScreens/%s.json", curChar))) chardata = json.parse(files.read_file(string.format("resultScreens/%s.json", curChar))) animationAliases = {} animationPositions = {} for index, anim in next, chardata.freeplayDJ.animations do animationAliases[anim.name] = anim.prefix animationPositions[anim.prefix] = Vector2(anim.offsets[1], anim.offsets[2]) end bfAtlas:stop() bfAtlas:load(string.format("sprites/freeplay/freeplay-%s", curChar)) print(animationAliases.intro) bfAtlas:play(animationAliases.intro) arrow = Sprite( string.format("sprites/freeplay/freeplaySelector-%s.png", curChar), string.format("sprites/freeplay/freeplaySelector-%s.json", curChar) ) arrow.position.y = 0 arrow.position.x = 40 arrow.layer = 50 arrow.flipX = false arrow:PlayAnimation("arrow pointer loop", 24, true) local arrow2 = Sprite( string.format("sprites/freeplay/freeplaySelector-%s.png", curChar), string.format("sprites/freeplay/freeplaySelector-%s.json", curChar) ) arrow2.position.y = 0 arrow2.position.x = 20 arrow2.layer = 50 arrow2.flipX = true arrow2:PlayAnimation("arrow pointer loop", 24, true) flip = false --reset the index's nd shit curSong = songs[1] curIndex = 1 evilCurIndex = 1 curDiffInd = 1 curDiffList = songs[curIndex].difficulties curDiff = curDiffList[1] diffIMG:PlayAnimation(curDiff, 24, true) charSwapSND:stop() charSwapSND:play() lastChange = 0 setupIcons() elseif key == "escape" then state.changeState("menustate") end end function state.load() setup() love.window.setMode(1280, 720, { fullscreen = false, resizable = false, centered = true, borderless = false }) end return state end