diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..30a4bc103 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,36 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + pull_request: + branches: [ main ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + # Runs a single command using the runners shell + - name: Run a one-line script + run: echo Hello, world! + + # Runs a set of commands using the runners shell + - name: Run a multi-line script + run: | + echo Add other actions to build, + echo test, and deploy your project. diff --git a/TitleState.hx b/TitleState.hx new file mode 100644 index 000000000..9016ea4c0 --- /dev/null +++ b/TitleState.hx @@ -0,0 +1,539 @@ +package; + +#if desktop +import Discord.DiscordClient; +import sys.thread.Thread; +#end +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.FlxState; +import flixel.input.keyboard.FlxKey; +import flixel.addons.display.FlxGridOverlay; +import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; +import flixel.addons.transition.FlxTransitionableState; +import flixel.addons.transition.TransitionData; +//import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxGroup; +import flixel.input.gamepad.FlxGamepad; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.system.FlxSound; +import flixel.system.ui.FlxSoundTray; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import lime.app.Application; +import openfl.Assets; +#if sys +import sys.FileSystem; +#end + +using StringTools; + +class TitleState extends MusicBeatState +{ + public static var muteKeys:Array = [FlxKey.ZERO]; + public static var volumeDownKeys:Array = [FlxKey.NUMPADMINUS, FlxKey.MINUS]; + public static var volumeUpKeys:Array = [FlxKey.NUMPADPLUS, FlxKey.PLUS]; + + static var initialized:Bool = false; + + var blackScreen:FlxSprite; + var backgroundTitle:FlxSprite + var credGroup:FlxGroup; + var credTextShit:Alphabet; + var textGroup:FlxGroup; + var logoSpr:FlxSprite; + + var curWacky:Array = []; + + var wackyImage:FlxSprite; + var easterEggEnabled:Bool = true; //Disable this to hide the easter egg +// #if desktop + var easterEggKeyCombination:Array = [FlxKey.B, FlxKey.B]; //bb stands for bbpanzu cuz he wanted this lmao +// #else // android +// var easterEggKeyCombination:Array = [controls.BACK, controls.BACK]; //backback stands for bbpanzu cuz he wanted this lmao +// #end +// #if desktop + var lastKeysPressed:Array = []; +// #else // android + //var lastKeysPressed:Array = []; + //#end + + var mustUpdate:Bool = false; + public static var updateVersion:String = ''; + + override public function create():Void + { + #if android + FlxG.android.preventDefaultKeys = [BACK]; + #end + + #if (polymod && !html5) + polymod.Polymod.init({modRoot: "mods", dirs: folders}); + #end + + #if CHECK_FOR_UPDATES + if(!closedState) { + trace('checking for update'); + var http = new haxe.Http(" "); + + http.onData = function (data:String) + { + updateVersion = data.split('\n')[0].trim(); + var curVersion:String = MainMenuState.psychEngineVersion.trim(); + trace('version online: ' + updateVersion + ', your version: ' + curVersion); + if(updateVersion != curVersion) { + trace('versions arent matching!'); + mustUpdate = true; + } + } + + http.onError = function (error) { + trace('error: $error'); + } + + http.request(); + } + #end + + FlxG.game.focusLostFramerate = 60; + FlxG.sound.muteKeys = muteKeys; + FlxG.sound.volumeDownKeys = volumeDownKeys; + FlxG.sound.volumeUpKeys = volumeUpKeys; + + PlayerSettings.init(); + + curWacky = FlxG.random.getObject(getIntroTextShit()); + + // DEBUG BULLSHIT + + swagShader = new ColorSwap(); + super.create(); + + FlxG.save.bind('funkin', 'ninjamuffin99'); + ClientPrefs.loadPrefs(); + + Highscore.load(); + + if (FlxG.save.data.weekCompleted != null) + { + StoryMenuState.weekCompleted = FlxG.save.data.weekCompleted; + } + + FlxG.mouse.visible = false; + #if FREEPLAY + MusicBeatState.switchState(new FreeplayState()); + #elseif CHARTING + MusicBeatState.switchState(new ChartingState()); + #else + if(FlxG.save.data.flashing == null && !FlashingState.leftState) { + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; + MusicBeatState.switchState(new FlashingState()); + } else { + #if desktop + DiscordClient.initialize(); + Application.current.onExit.add (function (exitCode) { + DiscordClient.shutdown(); + }); + #end + new FlxTimer().start(1, function(tmr:FlxTimer) + { + startIntro(); + }); + } + #end + } + + var logoBl:FlxSprite; + var gfDance:FlxSprite; + var danceLeft:Bool = false; + var titleText:FlxSprite; + var swagShader:ColorSwap = null; + + function startIntro() + { + if (!initialized) + { + /*var diamond:FlxGraphic = FlxGraphic.fromClass(GraphicTransTileDiamond); + diamond.persist = true; + diamond.destroyOnNoUse = false; + + FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 1, new FlxPoint(0, -1), {asset: diamond, width: 32, height: 32}, + new FlxRect(-300, -300, FlxG.width * 1.8, FlxG.height * 1.8)); + FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 0.7, new FlxPoint(0, 1), + {asset: diamond, width: 32, height: 32}, new FlxRect(-300, -300, FlxG.width * 1.8, FlxG.height * 1.8)); + + transIn = FlxTransitionableState.defaultTransIn; + transOut = FlxTransitionableState.defaultTransOut;*/ + + // HAD TO MODIFY SOME BACKEND SHIT + // IF THIS PR IS HERE IF ITS ACCEPTED UR GOOD TO GO + // https://github.com/HaxeFlixel/flixel-addons/pull/348 + + // var music:FlxSound = new FlxSound(); + // music.loadStream(Paths.music('freakyMenu')); + // FlxG.sound.list.add(music); + // music.play(); + + if(FlxG.sound.music == null) { + FlxG.sound.playMusic(Paths.music('freakyMenu'), 0); + + FlxG.sound.music.fadeIn(4, 0, 0.7); + } + } + + Conductor.changeBPM(102); + persistentUpdate = true; + + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + // bg.antialiasing = ClientPrefs.globalAntialiasing; + // bg.setGraphicSize(Std.int(bg.width * 0.6)); + // bg.updateHitbox(); + add(bg); + + logoBl = new FlxSprite(-150, -100); + logoBl.frames = Paths.getSparrowAtlas('logoBumpin'); + logoBl.antialiasing = ClientPrefs.globalAntialiasing; + logoBl.animation.addByPrefix('bump', 'logo bumpin', 24); + logoBl.animation.play('bump'); + logoBl.updateHitbox(); + logoBl.screenCenter(); + // logoBl.color = FlxColor.BLACK; + + backgroundTitle = new FlxSprite().loadGraphic(Paths.image('menuBG')); + backgroundTitle.screenCenter(); + backgroundTitle.antialiasing = ClientPrefs.globalAntialiasing; + + swagShader = new ColorSwap(); + if(!FlxG.save.data.psykaEasterEgg || !easterEggEnabled) { + gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.07); + gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle'); + gfDance.animation.addByIndices('danceLeft', 'gfDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + gfDance.animation.addByIndices('danceRight', 'gfDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + } + else //Psyka easter egg + { + gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.04); + gfDance.frames = Paths.getSparrowAtlas('psykaDanceTitle'); + gfDance.animation.addByIndices('danceLeft', 'psykaDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + gfDance.animation.addByIndices('danceRight', 'psykaDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + } + gfDance.antialiasing = ClientPrefs.globalAntialiasing; + add(backgroundTitle); + // add(gfDance); + gfDance.shader = swagShader.shader; + add(logoBl); + //logoBl.shader = swagShader.shader; + + titleText = new FlxSprite(100, FlxG.height * 0.8); + titleText.frames = Paths.getSparrowAtlas('titleEnter'); + titleText.animation.addByPrefix('idle', "Press Enter to Begin", 24); + titleText.animation.addByPrefix('press', "ENTER PRESSED", 24); + titleText.antialiasing = ClientPrefs.globalAntialiasing; + titleText.animation.play('idle'); + titleText.updateHitbox(); + // titleText.screenCenter(X); + add(titleText); + + var logo:FlxSprite = new FlxSprite().loadGraphic(Paths.image('logo')); + logo.screenCenter(); + logo.antialiasing = ClientPrefs.globalAntialiasing; + // add(logo); + + FlxTween.tween(logoBl, {y: logoBl.y + 50}, 0.6, {ease: FlxEase.quadInOut, type: PINGPONG}); + // FlxTween.tween(logo, {y: logoBl.y + 50}, 0.6, {ease: FlxEase.quadInOut, type: PINGPONG, startDelay: 0.1}); + + credGroup = new FlxGroup(); + add(credGroup); + textGroup = new FlxGroup(); + + blackScreen = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + credGroup.add(blackScreen); + + credTextShit = new Alphabet(0, 0, "", true); + credTextShit.screenCenter(); + + // credTextShit.alignment = CENTER; + + credTextShit.visible = false; + + logoSpr = new FlxSprite(0, FlxG.height * 0.4).loadGraphic(Paths.image('titlelogo')); + add(logoSpr); + logoSpr.visible = false; + logoSpr.setGraphicSize(Std.int(logoSpr.width * 0.55)); + logoSpr.updateHitbox(); + logoSpr.screenCenter(X); + logoSpr.antialiasing = ClientPrefs.globalAntialiasing; + + FlxTween.tween(credTextShit, {y: credTextShit.y + 20}, 2.9, {ease: FlxEase.quadInOut, type: PINGPONG}); + + if (initialized) + skipIntro(); + else + initialized = true; + + // credGroup.add(credTextShit); + } + + function getIntroTextShit():Array> + { + var fullText:String = Assets.getText(Paths.txt('introText')); + + var firstArray:Array = fullText.split('\n'); + var swagGoodArray:Array> = []; + + for (i in firstArray) + { + swagGoodArray.push(i.split('--')); + } + + return swagGoodArray; + } + + var transitioning:Bool = false; + + override function update(elapsed:Float) + { + if (FlxG.sound.music != null) + Conductor.songPosition = FlxG.sound.music.time; + // FlxG.watch.addQuick('amp', FlxG.sound.music.amplitude); + + if (FlxG.keys.justPressed.F) + { + FlxG.fullscreen = !FlxG.fullscreen; + } + + var pressedEnter:Bool = FlxG.keys.justPressed.ENTER; + + #if mobile + for (touch in FlxG.touches.list) + { + if (touch.justPressed) + { + pressedEnter = true; + } + } + #end + + var gamepad:FlxGamepad = FlxG.gamepads.lastActive; + + if (gamepad != null) + { + if (gamepad.justPressed.START) + pressedEnter = true; + + #if switch + if (gamepad.justPressed.B) + pressedEnter = true; + #end + } + + // EASTER EGG + + if (!transitioning && skippedIntro) + { + if(pressedEnter) + { + if(titleText != null) titleText.animation.play('press'); + + FlxG.camera.flash(FlxColor.WHITE, 1); + FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); + + transitioning = true; + // FlxG.sound.music.stop(); + + new FlxTimer().start(1, function(tmr:FlxTimer) + { + if (mustUpdate) { + MusicBeatState.switchState(new OutdatedState()); + } else { + MusicBeatState.switchState(new MainMenuState()); + } + closedState = true; + }); + // FlxG.sound.play(Paths.music('titleShoot'), 0.7); + } + else if(easterEggEnabled) + { + var finalKey:FlxKey = FlxG.keys.firstJustPressed(); + if(finalKey != FlxKey.NONE) { + lastKeysPressed.push(finalKey); //Convert int to FlxKey + if(lastKeysPressed.length > easterEggKeyCombination.length) + { + lastKeysPressed.shift(); + } + + if(lastKeysPressed.length == easterEggKeyCombination.length) + { + var isDifferent:Bool = false; + for (i in 0...lastKeysPressed.length) { + if(lastKeysPressed[i] != easterEggKeyCombination[i]) { + isDifferent = true; + break; + } + } + + if(!isDifferent) { + trace('Easter egg triggered!'); + FlxG.save.data.psykaEasterEgg = !FlxG.save.data.psykaEasterEgg; + FlxG.sound.play(Paths.sound('secretSound')); + + var black:FlxSprite = new FlxSprite(0, 0).makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + black.alpha = 0; + add(black); + + FlxTween.tween(black, {alpha: 1}, 1, {onComplete: + function(twn:FlxTween) { + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; + MusicBeatState.switchState(new TitleState()); + } + }); + lastKeysPressed = []; + closedState = true; + transitioning = true; + } + } + } + } + } + + if (pressedEnter && !skippedIntro) + { + skipIntro(); + } + + if(swagShader != null) + { + if(controls.UI_LEFT) swagShader.hue -= elapsed * 0.1; + if(controls.UI_RIGHT) swagShader.hue += elapsed * 0.1; + } + + super.update(elapsed); + } + + function createCoolText(textArray:Array, ?offset:Float = 0) + { + for (i in 0...textArray.length) + { + var money:Alphabet = new Alphabet(0, 0, textArray[i], true, false); + money.screenCenter(X); + money.y += (i * 60) + 200 + offset; + credGroup.add(money); + textGroup.add(money); + } + } + + function addMoreText(text:String, ?offset:Float = 0) + { + if(textGroup != null) { + var coolText:Alphabet = new Alphabet(0, 0, text, true, false); + coolText.screenCenter(X); + coolText.y += (textGroup.length * 60) + 200 + offset; + credGroup.add(coolText); + textGroup.add(coolText); + } + } + + function deleteCoolText() + { + while (textGroup.members.length > 0) + { + credGroup.remove(textGroup.members[0], true); + textGroup.remove(textGroup.members[0], true); + } + } + + private var sickBeats:Int = 0; //Basically curBeat but won't be skipped if you hold the tab or resize the screen + private static var closedState:Bool = false; + override function beatHit() + { + super.beatHit(); + + if(logoBl != null) + logoBl.animation.play('bump'); + + if(gfDance != null) { + danceLeft = !danceLeft; + + if (danceLeft) + gfDance.animation.play('danceRight'); + else + gfDance.animation.play('danceLeft'); + } + + if(!closedState) { + sickBeats++; + switch (sickBeats) + { + case 1: + createCoolText(['Psych Engine by'], 45); + // credTextShit.visible = true; + case 3: + addMoreText('Shadow Mario', 45); + addMoreText('RiverOaken', 45); + // credTextShit.text += '\npresent...'; + // credTextShit.addText(); + case 4: + deleteCoolText(); + // credTextShit.visible = false; + // credTextShit.text = 'In association \nwith'; + // credTextShit.screenCenter(); + case 5: + createCoolText(['This is a mod to'], -60); + case 7: + addMoreText('This game right below lol', -60); + logoSpr.visible = true; + // credTextShit.text += '\nNewgrounds'; + case 8: + deleteCoolText(); + logoSpr.visible = false; + // credTextShit.visible = false; + + // credTextShit.text = 'Shoutouts Tom Fulp'; + // credTextShit.screenCenter(); + case 9: + createCoolText([curWacky[0]]); + // credTextShit.visible = true; + case 11: + addMoreText(curWacky[1]); + // credTextShit.text += '\nlmao'; + case 12: + deleteCoolText(); + // credTextShit.visible = false; + // credTextShit.text = "Friday"; + // credTextShit.screenCenter(); + case 13: + addMoreText('Friday'); + // credTextShit.visible = true; + case 14: + addMoreText('Night'); + // credTextShit.text += '\nNight'; + case 15: + addMoreText('Funkin'); // credTextShit.text += '\nFunkin'; + + case 16: + skipIntro(); + } + } + } + + var skippedIntro:Bool = false; + + function skipIntro():Void + { + if (!skippedIntro) + { + remove(logoSpr); + + FlxG.camera.flash(FlxColor.WHITE, 4); + remove(credGroup); + skippedIntro = true; + } + } +} \ No newline at end of file