diff --git a/assets/shared/images/NOTE_assets.png b/assets/shared/images/NOTE_assets.png index 7d506361..72d42714 100644 Binary files a/assets/shared/images/NOTE_assets.png and b/assets/shared/images/NOTE_assets.png differ diff --git a/assets/shared/images/NOTE_assets.xml b/assets/shared/images/NOTE_assets.xml index 82a997a1..804182be 100644 --- a/assets/shared/images/NOTE_assets.xml +++ b/assets/shared/images/NOTE_assets.xml @@ -1,4 +1,4 @@ - + diff --git a/buildnumber.txt b/buildnumber.txt new file mode 100644 index 00000000..d8263ee9 --- /dev/null +++ b/buildnumber.txt @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/source/ChartingState.hx b/source/ChartingState.hx index 9ad46f1b..12130b3f 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -32,6 +32,8 @@ import openfl.media.Sound; import openfl.net.FileReference; import openfl.utils.ByteArray; +import funkin.game.Note; + using StringTools; class ChartingState extends MusicBeatState diff --git a/source/ControlsSubState.hx b/source/ControlsSubState.hx deleted file mode 100644 index f35d74cc..00000000 --- a/source/ControlsSubState.hx +++ /dev/null @@ -1,12 +0,0 @@ -package; - -import flixel.FlxSprite; -import flixel.FlxSubState; - -class ControlsSubState extends FlxSubState -{ - public function new() - { - super(); - } -} diff --git a/source/DialogueBox.hx b/source/DialogueBox.hx deleted file mode 100644 index 929eb242..00000000 --- a/source/DialogueBox.hx +++ /dev/null @@ -1,260 +0,0 @@ -package; - -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.addons.text.FlxTypeText; -import flixel.graphics.frames.FlxAtlasFrames; -import flixel.group.FlxSpriteGroup; -import flixel.input.FlxKeyManager; -import flixel.text.FlxText; -import flixel.util.FlxColor; -import flixel.util.FlxTimer; - -using StringTools; - -class DialogueBox extends FlxSpriteGroup -{ - var box:FlxSprite; - - var curCharacter:String = ''; - - var dialogue:Alphabet; - var dialogueList:Array = []; - - // SECOND DIALOGUE FOR THE PIXEL SHIT INSTEAD??? - var swagDialogue:FlxTypeText; - - var dropText:FlxText; - - public var finishThing:Void->Void; - - var portraitLeft:FlxSprite; - var portraitRight:FlxSprite; - - var handSelect:FlxSprite; - var bgFade:FlxSprite; - - public function new(talkingRight:Bool = true, ?dialogueList:Array) - { - super(); - - switch (PlayState.SONG.song.toLowerCase()) - { - case 'senpai': - FlxG.sound.playMusic(Paths.music('Lunchbox'), 0); - FlxG.sound.music.fadeIn(1, 0, 0.8); - case 'thorns': - FlxG.sound.playMusic(Paths.music('LunchboxScary'), 0); - FlxG.sound.music.fadeIn(1, 0, 0.8); - } - - bgFade = new FlxSprite(-200, -200).makeGraphic(Std.int(FlxG.width * 1.3), Std.int(FlxG.height * 1.3), 0xFFB3DFd8); - bgFade.scrollFactor.set(); - bgFade.alpha = 0; - add(bgFade); - - new FlxTimer().start(0.83, function(tmr:FlxTimer) - { - bgFade.alpha += (1 / 5) * 0.7; - if (bgFade.alpha > 0.7) - bgFade.alpha = 0.7; - }, 5); - - box = new FlxSprite(-20, 45); - - var hasDialog = false; - switch (PlayState.SONG.song.toLowerCase()) - { - case 'senpai': - hasDialog = true; - box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-pixel'); - box.animation.addByPrefix('normalOpen', 'Text Box Appear', 24, false); - box.animation.addByIndices('normal', 'Text Box Appear', [4], "", 24); - case 'roses': - hasDialog = true; - FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX')); - - box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-senpaiMad'); - box.animation.addByPrefix('normalOpen', 'SENPAI ANGRY IMPACT SPEECH', 24, false); - box.animation.addByIndices('normal', 'SENPAI ANGRY IMPACT SPEECH', [4], "", 24); - - case 'thorns': - hasDialog = true; - box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-evil'); - box.animation.addByPrefix('normalOpen', 'Spirit Textbox spawn', 24, false); - box.animation.addByIndices('normal', 'Spirit Textbox spawn', [11], "", 24); - - var face:FlxSprite = new FlxSprite(320, 170).loadGraphic(Paths.image('weeb/spiritFaceForward')); - face.setGraphicSize(Std.int(face.width * 6)); - add(face); - } - - this.dialogueList = dialogueList; - - if (!hasDialog) - return; - - portraitLeft = new FlxSprite(-20, 40); - portraitLeft.frames = Paths.getSparrowAtlas('weeb/senpaiPortrait'); - portraitLeft.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); - portraitLeft.setGraphicSize(Std.int(portraitLeft.width * PlayState.daPixelZoom * 0.9)); - portraitLeft.updateHitbox(); - portraitLeft.scrollFactor.set(); - add(portraitLeft); - portraitLeft.visible = false; - - portraitRight = new FlxSprite(0, 40); - portraitRight.frames = Paths.getSparrowAtlas('weeb/bfPortrait'); - portraitRight.animation.addByPrefix('enter', 'Boyfriend portrait enter', 24, false); - portraitRight.setGraphicSize(Std.int(portraitRight.width * PlayState.daPixelZoom * 0.9)); - portraitRight.updateHitbox(); - portraitRight.scrollFactor.set(); - add(portraitRight); - portraitRight.visible = false; - - box.animation.play('normalOpen'); - box.setGraphicSize(Std.int(box.width * PlayState.daPixelZoom * 0.9)); - box.updateHitbox(); - add(box); - - box.screenCenter(X); - portraitLeft.screenCenter(X); - - handSelect = new FlxSprite(FlxG.width * 0.9, FlxG.height * 0.9).loadGraphic(Paths.image('weeb/pixelUI/hand_textbox')); - add(handSelect); - - - if (!talkingRight) - { - // box.flipX = true; - } - - dropText = new FlxText(242, 502, Std.int(FlxG.width * 0.6), "", 32); - dropText.font = 'Pixel Arial 11 Bold'; - dropText.color = 0xFFD89494; - add(dropText); - - swagDialogue = new FlxTypeText(240, 500, Std.int(FlxG.width * 0.6), "", 32); - swagDialogue.font = 'Pixel Arial 11 Bold'; - swagDialogue.color = 0xFF3F2021; - swagDialogue.sounds = [FlxG.sound.load(Paths.sound('pixelText'), 0.6)]; - add(swagDialogue); - - dialogue = new Alphabet(0, 80, "", false, true); - // dialogue.x = 90; - // add(dialogue); - } - - var dialogueOpened:Bool = false; - var dialogueStarted:Bool = false; - - override function update(elapsed:Float) - { - // HARD CODING CUZ IM STUPDI - if (PlayState.SONG.song.toLowerCase() == 'roses') - portraitLeft.visible = false; - if (PlayState.SONG.song.toLowerCase() == 'thorns') - { - portraitLeft.color = FlxColor.BLACK; - swagDialogue.color = FlxColor.WHITE; - dropText.color = FlxColor.BLACK; - } - - dropText.text = swagDialogue.text; - - if (box.animation.curAnim != null) - { - if (box.animation.curAnim.name == 'normalOpen' && box.animation.curAnim.finished) - { - box.animation.play('normal'); - dialogueOpened = true; - } - } - - if (dialogueOpened && !dialogueStarted) - { - startDialogue(); - dialogueStarted = true; - } - - if (FlxG.keys.justPressed.ANY && dialogueStarted == true) - { - remove(dialogue); - - FlxG.sound.play(Paths.sound('clickText'), 0.8); - - if (dialogueList[1] == null && dialogueList[0] != null) - { - if (!isEnding) - { - isEnding = true; - - if (PlayState.SONG.song.toLowerCase() == 'senpai' || PlayState.SONG.song.toLowerCase() == 'thorns') - FlxG.sound.music.fadeOut(2.2, 0); - - new FlxTimer().start(0.2, function(tmr:FlxTimer) - { - box.alpha -= 1 / 5; - bgFade.alpha -= 1 / 5 * 0.7; - portraitLeft.visible = false; - portraitRight.visible = false; - swagDialogue.alpha -= 1 / 5; - dropText.alpha = swagDialogue.alpha; - }, 5); - - new FlxTimer().start(1.2, function(tmr:FlxTimer) - { - finishThing(); - kill(); - }); - } - } - else - { - dialogueList.remove(dialogueList[0]); - startDialogue(); - } - } - - super.update(elapsed); - } - - var isEnding:Bool = false; - - function startDialogue():Void - { - cleanDialog(); - // var theDialog:Alphabet = new Alphabet(0, 70, dialogueList[0], false, true); - // dialogue = theDialog; - // add(theDialog); - - // swagDialogue.text = ; - swagDialogue.resetText(dialogueList[0]); - swagDialogue.start(0.04, true); - - switch (curCharacter) - { - case 'dad': - portraitRight.visible = false; - if (!portraitLeft.visible) - { - portraitLeft.visible = true; - portraitLeft.animation.play('enter'); - } - case 'bf': - portraitLeft.visible = false; - if (!portraitRight.visible) - { - portraitRight.visible = true; - portraitRight.animation.play('enter'); - } - } - } - - function cleanDialog():Void - { - var splitName:Array = dialogueList[0].split(":"); - curCharacter = splitName[1]; - dialogueList[0] = dialogueList[0].substr(splitName[1].length + 2).trim(); - } -} diff --git a/source/Main.hx b/source/Main.hx index 5208cad4..a4806471 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -12,6 +12,7 @@ import flixel.FlxG; // TODO: REMOVE TEST import modsfolder.ModsFolder; +@:build(funkin.macros.BuildCounterMacro.build()) class Main extends Sprite { var gameWidth:Int = 1280; // Width of the game in pixels (might be less / more in actual pixels depending on your zoom). @@ -88,5 +89,7 @@ class Main extends Sprite ModsFolder.loadMod("B-Sides"); ModsFolder.currentModFolder = "B-Sides"; + + FlxG.fixedTimestep = false; } } diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index ac22c703..8e7f33ff 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -95,9 +95,11 @@ class MainMenuState extends MusicBeatState FlxG.camera.follow(camFollow, null, 0.06); - var versionShit:FlxText = new FlxText(5, FlxG.height - 18, 0, "v" + Application.current.meta.get('version'), 12); + trace(Main.buildNumber); + var versionShit:FlxText = new FlxText(5, FlxG.height - 2, 0, 'Codename Engine v${Application.current.meta.get('version')}\r\nPre-Alpha: Build ${Main.buildNumber}', 12); versionShit.scrollFactor.set(); versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + versionShit.y -= versionShit.height; add(versionShit); // NG.core.calls.event.logEvent('swag').send(); @@ -183,7 +185,7 @@ class MainMenuState extends MusicBeatState case 'options': FlxTransitionableState.skipNextTransIn = true; FlxTransitionableState.skipNextTransOut = true; - FlxG.switchState(new OptionsMenu()); + // FlxG.switchState(new OptionsMenu()); } }); } diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx index 88c58a62..6deaccdf 100644 --- a/source/MusicBeatState.hx +++ b/source/MusicBeatState.hx @@ -14,6 +14,8 @@ class MusicBeatState extends FlxUIState private var curStep:Int = 0; private var curBeat:Int = 0; + private var curStepFloat:Float = 0; + private var curBeatFloat:Float = 0; private var controls(get, never):Controls; inline function get_controls():Controls @@ -43,7 +45,7 @@ class MusicBeatState extends FlxUIState private function updateBeat():Void { - curBeat = Math.floor(curStep / 4); + curBeat = Math.floor(curBeatFloat = (curStep / 4)); } private function updateCurStep():Void @@ -59,7 +61,7 @@ class MusicBeatState extends FlxUIState lastChange = Conductor.bpmChangeMap[i]; } - curStep = lastChange.stepTime + Math.floor((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet); + curStep = Math.floor(curStepFloat = lastChange.stepTime + ((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet)); } public function stepHit():Void diff --git a/source/OptionsMenu.hx b/source/OptionsMenu.hx deleted file mode 100644 index 37f3987a..00000000 --- a/source/OptionsMenu.hx +++ /dev/null @@ -1,130 +0,0 @@ -package; - -import Controls.Control; -import flash.text.TextField; -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.addons.display.FlxGridOverlay; -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.input.keyboard.FlxKey; -import flixel.math.FlxMath; -import flixel.text.FlxText; -import flixel.util.FlxColor; -import lime.utils.Assets; - -class OptionsMenu extends MusicBeatState -{ - var selector:FlxText; - var curSelected:Int = 0; - - var controlsStrings:Array = []; - - private var grpControls:FlxTypedGroup; - - override function create() - { - var menuBG:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuDesat')); - controlsStrings = CoolUtil.coolTextFile(Paths.txt('controls')); - menuBG.color = 0xFFea71fd; - menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); - menuBG.updateHitbox(); - menuBG.screenCenter(); - menuBG.antialiasing = true; - add(menuBG); - - /* - grpControls = new FlxTypedGroup(); - add(grpControls); - - for (i in 0...controlsStrings.length) - { - if (controlsStrings[i].indexOf('set') != -1) - { - var controlLabel:Alphabet = new Alphabet(0, (70 * i) + 30, controlsStrings[i].substring(3) + ': ' + controlsStrings[i + 1], true, false); - controlLabel.isMenuItem = true; - controlLabel.targetY = i; - grpControls.add(controlLabel); - } - // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! - } - */ - - super.create(); - - openSubState(new OptionsSubState()); - } - - override function update(elapsed:Float) - { - super.update(elapsed); - - /* - if (controls.ACCEPT) - { - changeBinding(); - } - - if (isSettingControl) - waitingInput(); - else - { - if (controls.BACK) - FlxG.switchState(new MainMenuState()); - if (controls.UP_P) - changeSelection(-1); - if (controls.DOWN_P) - changeSelection(1); - } - */ - } - - function waitingInput():Void - { - if (FlxG.keys.getIsDown().length > 0) - { - PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxG.keys.getIsDown()[0].ID, null); - } - // PlayerSettings.player1.controls.replaceBinding(Control) - } - - var isSettingControl:Bool = false; - - function changeBinding():Void - { - if (!isSettingControl) - { - isSettingControl = true; - } - } - - function changeSelection(change:Int = 0) - { - FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); - - curSelected += change; - - if (curSelected < 0) - curSelected = grpControls.length - 1; - if (curSelected >= grpControls.length) - curSelected = 0; - - // selector.y = (70 * curSelected) + 30; - - var bullShit:Int = 0; - - for (item in grpControls.members) - { - item.targetY = bullShit - curSelected; - bullShit++; - - item.alpha = 0.6; - // item.setGraphicSize(Std.int(item.width * 0.8)); - - if (item.targetY == 0) - { - item.alpha = 1; - // item.setGraphicSize(Std.int(item.width)); - } - } - } -} diff --git a/source/OptionsSubState.hx b/source/OptionsSubState.hx deleted file mode 100644 index 2b63e0c2..00000000 --- a/source/OptionsSubState.hx +++ /dev/null @@ -1,70 +0,0 @@ -package; - -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.text.FlxText; -import flixel.util.FlxColor; - -class OptionsSubState extends MusicBeatSubstate -{ - var textMenuItems:Array = ['Master Volume', 'Sound Volume', 'Controls']; - - var selector:FlxSprite; - var curSelected:Int = 0; - - var grpOptionsTexts:FlxTypedGroup; - - public function new() - { - super(); - - grpOptionsTexts = new FlxTypedGroup(); - add(grpOptionsTexts); - - selector = new FlxSprite().makeGraphic(5, 5, FlxColor.RED); - add(selector); - - for (i in 0...textMenuItems.length) - { - var optionText:FlxText = new FlxText(20, 20 + (i * 50), 0, textMenuItems[i], 32); - optionText.ID = i; - grpOptionsTexts.add(optionText); - } - } - - override function update(elapsed:Float) - { - super.update(elapsed); - - if (controls.UP_P) - curSelected -= 1; - - if (controls.DOWN_P) - curSelected += 1; - - if (curSelected < 0) - curSelected = textMenuItems.length - 1; - - if (curSelected >= textMenuItems.length) - curSelected = 0; - - grpOptionsTexts.forEach(function(txt:FlxText) - { - txt.color = FlxColor.WHITE; - - if (txt.ID == curSelected) - txt.color = FlxColor.YELLOW; - }); - - if (controls.ACCEPT) - { - switch (textMenuItems[curSelected]) - { - case "Controls": - FlxG.state.closeSubState(); - FlxG.state.openSubState(new ControlsSubState()); - } - } - } -} diff --git a/source/PlayState.hx b/source/PlayState.hx deleted file mode 100644 index 3b4d9689..00000000 --- a/source/PlayState.hx +++ /dev/null @@ -1,2465 +0,0 @@ -package; - -#if desktop -import Discord.DiscordClient; -#end -import Section.SwagSection; -import Song.SwagSong; -import WiggleEffect.WiggleEffectType; -import flixel.FlxBasic; -import flixel.FlxCamera; -import flixel.FlxG; -import flixel.FlxGame; -import flixel.FlxObject; -import flixel.FlxSprite; -import flixel.FlxState; -import flixel.FlxSubState; -import flixel.addons.display.FlxGridOverlay; -import flixel.addons.effects.FlxTrail; -import flixel.addons.effects.FlxTrailArea; -import flixel.addons.effects.chainable.FlxEffectSprite; -import flixel.addons.effects.chainable.FlxWaveEffect; -import flixel.addons.transition.FlxTransitionableState; -import flixel.graphics.atlas.FlxAtlas; -import flixel.graphics.frames.FlxAtlasFrames; -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.math.FlxMath; -import flixel.math.FlxPoint; -import flixel.math.FlxRect; -import flixel.system.FlxSound; -import flixel.text.FlxText; -import flixel.tweens.FlxEase; -import flixel.tweens.FlxTween; -import flixel.ui.FlxBar; -import flixel.util.FlxCollision; -import flixel.util.FlxColor; -import flixel.util.FlxSort; -import flixel.util.FlxStringUtil; -import flixel.util.FlxTimer; -import haxe.Json; -import lime.utils.Assets; -import openfl.display.BlendMode; -import openfl.display.StageQuality; -import openfl.filters.ShaderFilter; - -using StringTools; - -class PlayState extends MusicBeatState -{ - public static var curStage:String = ''; - public static var SONG:SwagSong; - public static var isStoryMode:Bool = false; - public static var storyWeek:Int = 0; - public static var storyPlaylist:Array = []; - public static var storyDifficulty:Int = 1; - - var halloweenLevel:Bool = false; - - private var vocals:FlxSound; - - private var dad:Character; - private var gf:Character; - private var boyfriend:Boyfriend; - - private var notes:FlxTypedGroup; - private var unspawnNotes:Array = []; - - private var strumLine:FlxSprite; - private var curSection:Int = 0; - - private var camFollow:FlxObject; - - private static var prevCamFollow:FlxObject; - - private var strumLineNotes:FlxTypedGroup; - private var playerStrums:FlxTypedGroup; - - private var camZooming:Bool = false; - private var curSong:String = ""; - - private var gfSpeed:Int = 1; - private var health:Float = 1; - private var combo:Int = 0; - - private var healthBarBG:FlxSprite; - private var healthBar:FlxBar; - - private var generatedMusic:Bool = false; - private var startingSong:Bool = false; - - private var iconP1:HealthIcon; - private var iconP2:HealthIcon; - private var camHUD:FlxCamera; - private var camGame:FlxCamera; - - var dialogue:Array = ['blah blah blah', 'coolswag']; - - var halloweenBG:FlxSprite; - var isHalloween:Bool = false; - - var phillyCityLights:FlxTypedGroup; - var phillyTrain:FlxSprite; - var trainSound:FlxSound; - - var limo:FlxSprite; - var grpLimoDancers:FlxTypedGroup; - var fastCar:FlxSprite; - - var upperBoppers:FlxSprite; - var bottomBoppers:FlxSprite; - var santa:FlxSprite; - - var bgGirls:BackgroundGirls; - var wiggleShit:WiggleEffect = new WiggleEffect(); - - var talking:Bool = true; - var songScore:Int = 0; - var scoreTxt:FlxText; - - public static var campaignScore:Int = 0; - - var defaultCamZoom:Float = 1.05; - - // how big to stretch the pixel art assets - public static var daPixelZoom:Float = 6; - - var inCutscene:Bool = false; - - #if desktop - // Discord RPC variables - var storyDifficultyText:String = ""; - var iconRPC:String = ""; - var songLength:Float = 0; - var detailsText:String = ""; - var detailsPausedText:String = ""; - #end - - override public function create() - { - if (FlxG.sound.music != null) - FlxG.sound.music.stop(); - - camGame = new FlxCamera(); - camHUD = new FlxCamera(); - camHUD.bgColor.alpha = 0; - - FlxG.cameras.reset(camGame); - FlxG.cameras.add(camHUD, false); - - persistentUpdate = true; - persistentDraw = true; - - if (SONG == null) - SONG = Song.loadFromJson('tutorial'); - - Conductor.mapBPMChanges(SONG); - Conductor.changeBPM(SONG.bpm); - - switch (SONG.song.toLowerCase()) - { - case 'tutorial': - dialogue = ["Hey you're pretty cute.", 'Use the arrow keys to keep up \nwith me singing.']; - case 'bopeebo': - dialogue = [ - 'HEY!', - "You think you can just sing\nwith my daughter like that?", - "If you want to date her...", - "You're going to have to go \nthrough ME first!" - ]; - case 'fresh': - dialogue = ["Not too shabby boy.", ""]; - case 'dadbattle': - dialogue = [ - "gah you think you're hot stuff?", - "If you can beat me here...", - "Only then I will even CONSIDER letting you\ndate my daughter!" - ]; - case 'senpai': - dialogue = CoolUtil.coolTextFile(Paths.txt('senpai/senpaiDialogue')); - case 'roses': - dialogue = CoolUtil.coolTextFile(Paths.txt('roses/rosesDialogue')); - case 'thorns': - dialogue = CoolUtil.coolTextFile(Paths.txt('thorns/thornsDialogue')); - } - - #if desktop - // Making difficulty text for Discord Rich Presence. - switch (storyDifficulty) - { - case 0: - storyDifficultyText = "Easy"; - case 1: - storyDifficultyText = "Normal"; - case 2: - storyDifficultyText = "Hard"; - } - - iconRPC = SONG.player2; - - // To avoid having duplicate images in Discord assets - switch (iconRPC) - { - case 'senpai-angry': - iconRPC = 'senpai'; - case 'monster-christmas': - iconRPC = 'monster'; - case 'mom-car': - iconRPC = 'mom'; - } - - // String that contains the mode defined here so it isn't necessary to call changePresence for each mode - if (isStoryMode) - { - detailsText = "Story Mode: Week " + storyWeek; - } - else - { - detailsText = "Freeplay"; - } - - // String for when the game is paused - detailsPausedText = "Paused - " + detailsText; - - // Updating Discord Rich Presence. - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); - #end - - switch (SONG.song.toLowerCase()) - { - case 'spookeez' | 'monster' | 'south': - { - curStage = 'spooky'; - halloweenLevel = true; - - var hallowTex = Paths.getSparrowAtlas('halloween_bg'); - - halloweenBG = new FlxSprite(-200, -100); - halloweenBG.frames = hallowTex; - halloweenBG.animation.addByPrefix('idle', 'halloweem bg0'); - halloweenBG.animation.addByPrefix('lightning', 'halloweem bg lightning strike', 24, false); - halloweenBG.animation.play('idle'); - halloweenBG.antialiasing = true; - add(halloweenBG); - - isHalloween = true; - } - case 'pico' | 'blammed' | 'philly': - { - curStage = 'philly'; - - var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky')); - bg.scrollFactor.set(0.1, 0.1); - add(bg); - - var city:FlxSprite = new FlxSprite(-10).loadGraphic(Paths.image('philly/city')); - city.scrollFactor.set(0.3, 0.3); - city.setGraphicSize(Std.int(city.width * 0.85)); - city.updateHitbox(); - add(city); - - phillyCityLights = new FlxTypedGroup(); - add(phillyCityLights); - - for (i in 0...5) - { - var light:FlxSprite = new FlxSprite(city.x).loadGraphic(Paths.image('philly/win' + i)); - light.scrollFactor.set(0.3, 0.3); - light.visible = false; - light.setGraphicSize(Std.int(light.width * 0.85)); - light.updateHitbox(); - light.antialiasing = true; - phillyCityLights.add(light); - } - - var streetBehind:FlxSprite = new FlxSprite(-40, 50).loadGraphic(Paths.image('philly/behindTrain')); - add(streetBehind); - - phillyTrain = new FlxSprite(2000, 360).loadGraphic(Paths.image('philly/train')); - add(phillyTrain); - - trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes')); - FlxG.sound.list.add(trainSound); - - // var cityLights:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.win0.png); - - var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic(Paths.image('philly/street')); - add(street); - } - case 'milf' | 'satin-panties' | 'high': - { - curStage = 'limo'; - defaultCamZoom = 0.90; - - var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic(Paths.image('limo/limoSunset')); - skyBG.scrollFactor.set(0.1, 0.1); - add(skyBG); - - var bgLimo:FlxSprite = new FlxSprite(-200, 480); - bgLimo.frames = Paths.getSparrowAtlas('limo/bgLimo'); - bgLimo.animation.addByPrefix('drive', "background limo pink", 24); - bgLimo.animation.play('drive'); - bgLimo.scrollFactor.set(0.4, 0.4); - add(bgLimo); - - grpLimoDancers = new FlxTypedGroup(); - add(grpLimoDancers); - - for (i in 0...5) - { - var dancer:BackgroundDancer = new BackgroundDancer((370 * i) + 130, bgLimo.y - 400); - dancer.scrollFactor.set(0.4, 0.4); - grpLimoDancers.add(dancer); - } - - var overlayShit:FlxSprite = new FlxSprite(-500, -600).loadGraphic(Paths.image('limo/limoOverlay')); - overlayShit.alpha = 0.5; - // add(overlayShit); - - // var shaderBullshit = new BlendModeEffect(new OverlayShader(), FlxColor.RED); - - // FlxG.camera.setFilters([new ShaderFilter(cast shaderBullshit.shader)]); - - // overlayShit.shader = shaderBullshit; - - var limoTex = Paths.getSparrowAtlas('limo/limoDrive'); - - limo = new FlxSprite(-120, 550); - limo.frames = limoTex; - limo.animation.addByPrefix('drive', "Limo stage", 24); - limo.animation.play('drive'); - limo.antialiasing = true; - - fastCar = new FlxSprite(-300, 160).loadGraphic(Paths.image('limo/fastCarLol')); - // add(limo); - } - case 'cocoa' | 'eggnog': - { - curStage = 'mall'; - - defaultCamZoom = 0.80; - - var bg:FlxSprite = new FlxSprite(-1000, -500).loadGraphic(Paths.image('christmas/bgWalls')); - bg.antialiasing = true; - bg.scrollFactor.set(0.2, 0.2); - bg.active = false; - bg.setGraphicSize(Std.int(bg.width * 0.8)); - bg.updateHitbox(); - add(bg); - - upperBoppers = new FlxSprite(-240, -90); - upperBoppers.frames = Paths.getSparrowAtlas('christmas/upperBop'); - upperBoppers.animation.addByPrefix('bop', "Upper Crowd Bob", 24, false); - upperBoppers.antialiasing = true; - upperBoppers.scrollFactor.set(0.33, 0.33); - upperBoppers.setGraphicSize(Std.int(upperBoppers.width * 0.85)); - upperBoppers.updateHitbox(); - add(upperBoppers); - - var bgEscalator:FlxSprite = new FlxSprite(-1100, -600).loadGraphic(Paths.image('christmas/bgEscalator')); - bgEscalator.antialiasing = true; - bgEscalator.scrollFactor.set(0.3, 0.3); - bgEscalator.active = false; - bgEscalator.setGraphicSize(Std.int(bgEscalator.width * 0.9)); - bgEscalator.updateHitbox(); - add(bgEscalator); - - var tree:FlxSprite = new FlxSprite(370, -250).loadGraphic(Paths.image('christmas/christmasTree')); - tree.antialiasing = true; - tree.scrollFactor.set(0.40, 0.40); - add(tree); - - bottomBoppers = new FlxSprite(-300, 140); - bottomBoppers.frames = Paths.getSparrowAtlas('christmas/bottomBop'); - bottomBoppers.animation.addByPrefix('bop', 'Bottom Level Boppers', 24, false); - bottomBoppers.antialiasing = true; - bottomBoppers.scrollFactor.set(0.9, 0.9); - bottomBoppers.setGraphicSize(Std.int(bottomBoppers.width * 1)); - bottomBoppers.updateHitbox(); - add(bottomBoppers); - - var fgSnow:FlxSprite = new FlxSprite(-600, 700).loadGraphic(Paths.image('christmas/fgSnow')); - fgSnow.active = false; - fgSnow.antialiasing = true; - add(fgSnow); - - santa = new FlxSprite(-840, 150); - santa.frames = Paths.getSparrowAtlas('christmas/santa'); - santa.animation.addByPrefix('idle', 'santa idle in fear', 24, false); - santa.antialiasing = true; - add(santa); - } - case 'winter-horrorland': - { - curStage = 'mallEvil'; - var bg:FlxSprite = new FlxSprite(-400, -500).loadGraphic(Paths.image('christmas/evilBG')); - bg.antialiasing = true; - bg.scrollFactor.set(0.2, 0.2); - bg.active = false; - bg.setGraphicSize(Std.int(bg.width * 0.8)); - bg.updateHitbox(); - add(bg); - - var evilTree:FlxSprite = new FlxSprite(300, -300).loadGraphic(Paths.image('christmas/evilTree')); - evilTree.antialiasing = true; - evilTree.scrollFactor.set(0.2, 0.2); - add(evilTree); - - var evilSnow:FlxSprite = new FlxSprite(-200, 700).loadGraphic(Paths.image("christmas/evilSnow")); - evilSnow.antialiasing = true; - add(evilSnow); - } - case 'senpai' | 'roses': - { - curStage = 'school'; - - // defaultCamZoom = 0.9; - - var bgSky = new FlxSprite().loadGraphic(Paths.image('weeb/weebSky')); - bgSky.scrollFactor.set(0.1, 0.1); - add(bgSky); - - var repositionShit = -200; - - var bgSchool:FlxSprite = new FlxSprite(repositionShit, 0).loadGraphic(Paths.image('weeb/weebSchool')); - bgSchool.scrollFactor.set(0.6, 0.90); - add(bgSchool); - - var bgStreet:FlxSprite = new FlxSprite(repositionShit).loadGraphic(Paths.image('weeb/weebStreet')); - bgStreet.scrollFactor.set(0.95, 0.95); - add(bgStreet); - - var fgTrees:FlxSprite = new FlxSprite(repositionShit + 170, 130).loadGraphic(Paths.image('weeb/weebTreesBack')); - fgTrees.scrollFactor.set(0.9, 0.9); - add(fgTrees); - - var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800); - var treetex = Paths.getPackerAtlas('weeb/weebTrees'); - bgTrees.frames = treetex; - bgTrees.animation.add('treeLoop', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 12); - bgTrees.animation.play('treeLoop'); - bgTrees.scrollFactor.set(0.85, 0.85); - add(bgTrees); - - var treeLeaves:FlxSprite = new FlxSprite(repositionShit, -40); - treeLeaves.frames = Paths.getSparrowAtlas('weeb/petals'); - treeLeaves.animation.addByPrefix('leaves', 'PETALS ALL', 24, true); - treeLeaves.animation.play('leaves'); - treeLeaves.scrollFactor.set(0.85, 0.85); - add(treeLeaves); - - var widShit = Std.int(bgSky.width * 6); - - bgSky.setGraphicSize(widShit); - bgSchool.setGraphicSize(widShit); - bgStreet.setGraphicSize(widShit); - bgTrees.setGraphicSize(Std.int(widShit * 1.4)); - fgTrees.setGraphicSize(Std.int(widShit * 0.8)); - treeLeaves.setGraphicSize(widShit); - - fgTrees.updateHitbox(); - bgSky.updateHitbox(); - bgSchool.updateHitbox(); - bgStreet.updateHitbox(); - bgTrees.updateHitbox(); - treeLeaves.updateHitbox(); - - bgGirls = new BackgroundGirls(-100, 190); - bgGirls.scrollFactor.set(0.9, 0.9); - - if (SONG.song.toLowerCase() == 'roses') - { - bgGirls.getScared(); - } - - bgGirls.setGraphicSize(Std.int(bgGirls.width * daPixelZoom)); - bgGirls.updateHitbox(); - add(bgGirls); - } - case 'thorns': - { - curStage = 'schoolEvil'; - - var waveEffectBG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 3, 2); - var waveEffectFG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 5, 2); - - var posX = 400; - var posY = 200; - - var bg:FlxSprite = new FlxSprite(posX, posY); - bg.frames = Paths.getSparrowAtlas('weeb/animatedEvilSchool'); - bg.animation.addByPrefix('idle', 'background 2', 24); - bg.animation.play('idle'); - bg.scrollFactor.set(0.8, 0.9); - bg.scale.set(6, 6); - add(bg); - - /* - var bg:FlxSprite = new FlxSprite(posX, posY).loadGraphic(Paths.image('weeb/evilSchoolBG')); - bg.scale.set(6, 6); - // bg.setGraphicSize(Std.int(bg.width * 6)); - // bg.updateHitbox(); - add(bg); - - var fg:FlxSprite = new FlxSprite(posX, posY).loadGraphic(Paths.image('weeb/evilSchoolFG')); - fg.scale.set(6, 6); - // fg.setGraphicSize(Std.int(fg.width * 6)); - // fg.updateHitbox(); - add(fg); - - wiggleShit.effectType = WiggleEffectType.DREAMY; - wiggleShit.waveAmplitude = 0.01; - wiggleShit.waveFrequency = 60; - wiggleShit.waveSpeed = 0.8; - */ - - // bg.shader = wiggleShit.shader; - // fg.shader = wiggleShit.shader; - - /* - var waveSprite = new FlxEffectSprite(bg, [waveEffectBG]); - var waveSpriteFG = new FlxEffectSprite(fg, [waveEffectFG]); - - // Using scale since setGraphicSize() doesnt work??? - waveSprite.scale.set(6, 6); - waveSpriteFG.scale.set(6, 6); - waveSprite.setPosition(posX, posY); - waveSpriteFG.setPosition(posX, posY); - - waveSprite.scrollFactor.set(0.7, 0.8); - waveSpriteFG.scrollFactor.set(0.9, 0.8); - - // waveSprite.setGraphicSize(Std.int(waveSprite.width * 6)); - // waveSprite.updateHitbox(); - // waveSpriteFG.setGraphicSize(Std.int(fg.width * 6)); - // waveSpriteFG.updateHitbox(); - - add(waveSprite); - add(waveSpriteFG); - */ - } - default: - { - defaultCamZoom = 0.9; - curStage = 'stage'; - var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(Paths.image('stageback')); - bg.antialiasing = true; - bg.scrollFactor.set(0.9, 0.9); - bg.active = false; - add(bg); - - var stageFront:FlxSprite = new FlxSprite(-650, 600).loadGraphic(Paths.image('stagefront')); - stageFront.setGraphicSize(Std.int(stageFront.width * 1.1)); - stageFront.updateHitbox(); - stageFront.antialiasing = true; - stageFront.scrollFactor.set(0.9, 0.9); - stageFront.active = false; - add(stageFront); - - var stageCurtains:FlxSprite = new FlxSprite(-500, -300).loadGraphic(Paths.image('stagecurtains')); - stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9)); - stageCurtains.updateHitbox(); - stageCurtains.antialiasing = true; - stageCurtains.scrollFactor.set(1.3, 1.3); - stageCurtains.active = false; - - add(stageCurtains); - } - } - - var gfVersion:String = 'gf'; - - switch (curStage) - { - case 'limo': - gfVersion = 'gf-car'; - case 'mall' | 'mallEvil': - gfVersion = 'gf-christmas'; - case 'school': - gfVersion = 'gf-pixel'; - case 'schoolEvil': - gfVersion = 'gf-pixel'; - } - - if (curStage == 'limo') - gfVersion = 'gf-car'; - - gf = new Character(400, 130, gfVersion); - gf.scrollFactor.set(0.95, 0.95); - - dad = new Character(100, 100, SONG.player2); - - var camPos:FlxPoint = new FlxPoint(dad.getGraphicMidpoint().x, dad.getGraphicMidpoint().y); - - switch (SONG.player2) - { - case 'gf': - dad.setPosition(gf.x, gf.y); - gf.visible = false; - if (isStoryMode) - { - camPos.x += 600; - tweenCamIn(); - } - - case "spooky": - dad.y += 200; - case "monster": - dad.y += 100; - case 'monster-christmas': - dad.y += 130; - case 'dad': - camPos.x += 400; - case 'pico': - camPos.x += 600; - dad.y += 300; - case 'parents-christmas': - dad.x -= 500; - case 'senpai': - dad.x += 150; - dad.y += 360; - camPos.set(dad.getGraphicMidpoint().x + 300, dad.getGraphicMidpoint().y); - case 'senpai-angry': - dad.x += 150; - dad.y += 360; - camPos.set(dad.getGraphicMidpoint().x + 300, dad.getGraphicMidpoint().y); - case 'spirit': - dad.x -= 150; - dad.y += 100; - camPos.set(dad.getGraphicMidpoint().x + 300, dad.getGraphicMidpoint().y); - } - - boyfriend = new Boyfriend(770, 450, SONG.player1); - - // REPOSITIONING PER STAGE - switch (curStage) - { - case 'limo': - boyfriend.y -= 220; - boyfriend.x += 260; - - resetFastCar(); - add(fastCar); - - case 'mall': - boyfriend.x += 200; - - case 'mallEvil': - boyfriend.x += 320; - dad.y -= 80; - case 'school': - boyfriend.x += 200; - boyfriend.y += 220; - gf.x += 180; - gf.y += 300; - case 'schoolEvil': - // trailArea.scrollFactor.set(); - - var evilTrail = new FlxTrail(dad, null, 4, 24, 0.3, 0.069); - // evilTrail.changeValuesEnabled(false, false, false, false); - // evilTrail.changeGraphic() - add(evilTrail); - // evilTrail.scrollFactor.set(1.1, 1.1); - - boyfriend.x += 200; - boyfriend.y += 220; - gf.x += 180; - gf.y += 300; - } - - add(gf); - - // Shitty layering but whatev it works LOL - if (curStage == 'limo') - add(limo); - - add(dad); - add(boyfriend); - - var doof:DialogueBox = new DialogueBox(false, dialogue); - // doof.x += 70; - // doof.y = FlxG.height * 0.5; - doof.scrollFactor.set(); - doof.finishThing = startCountdown; - - Conductor.songPosition = -5000; - - strumLine = new FlxSprite(0, 50).makeGraphic(FlxG.width, 10); - strumLine.scrollFactor.set(); - - strumLineNotes = new FlxTypedGroup(); - add(strumLineNotes); - - playerStrums = new FlxTypedGroup(); - - // startCountdown(); - - generateSong(SONG.song); - - // add(strumLine); - - camFollow = new FlxObject(0, 0, 1, 1); - - camFollow.setPosition(camPos.x, camPos.y); - - if (prevCamFollow != null) - { - camFollow = prevCamFollow; - prevCamFollow = null; - } - - add(camFollow); - - FlxG.camera.follow(camFollow, LOCKON, 0.04); - // FlxG.camera.setScrollBounds(0, FlxG.width, 0, FlxG.height); - FlxG.camera.zoom = defaultCamZoom; - FlxG.camera.focusOn(camFollow.getPosition()); - - FlxG.worldBounds.set(0, 0, FlxG.width, FlxG.height); - - FlxG.fixedTimestep = false; - - healthBarBG = new FlxSprite(0, FlxG.height * 0.9).loadGraphic(Paths.image('healthBar')); - healthBarBG.screenCenter(X); - healthBarBG.scrollFactor.set(); - add(healthBarBG); - - healthBar = new FlxBar(healthBarBG.x + 4, healthBarBG.y + 4, RIGHT_TO_LEFT, Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, - 'health', 0, 2); - healthBar.scrollFactor.set(); - healthBar.createFilledBar(0xFFFF0000, 0xFF66FF33); - // healthBar - add(healthBar); - - scoreTxt = new FlxText(healthBarBG.x + healthBarBG.width - 190, healthBarBG.y + 30, 0, "", 20); - scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT); - scoreTxt.scrollFactor.set(); - add(scoreTxt); - - iconP1 = new HealthIcon(SONG.player1, true); - iconP1.y = healthBar.y - (iconP1.height / 2); - add(iconP1); - - iconP2 = new HealthIcon(SONG.player2, false); - iconP2.y = healthBar.y - (iconP2.height / 2); - add(iconP2); - - strumLineNotes.cameras = [camHUD]; - notes.cameras = [camHUD]; - healthBar.cameras = [camHUD]; - healthBarBG.cameras = [camHUD]; - iconP1.cameras = [camHUD]; - iconP2.cameras = [camHUD]; - scoreTxt.cameras = [camHUD]; - doof.cameras = [camHUD]; - - // if (SONG.song == 'South') - // FlxG.camera.alpha = 0.7; - // UI_camera.zoom = 1; - - // cameras = [FlxG.cameras.list[1]]; - startingSong = true; - - if (isStoryMode) - { - switch (curSong.toLowerCase()) - { - case "winter-horrorland": - var blackScreen:FlxSprite = new FlxSprite(0, 0).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK); - add(blackScreen); - blackScreen.scrollFactor.set(); - camHUD.visible = false; - - new FlxTimer().start(0.1, function(tmr:FlxTimer) - { - remove(blackScreen); - FlxG.sound.play(Paths.sound('Lights_Turn_On')); - camFollow.y = -2050; - camFollow.x += 200; - FlxG.camera.focusOn(camFollow.getPosition()); - FlxG.camera.zoom = 1.5; - - new FlxTimer().start(0.8, function(tmr:FlxTimer) - { - camHUD.visible = true; - remove(blackScreen); - FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom}, 2.5, { - ease: FlxEase.quadInOut, - onComplete: function(twn:FlxTween) - { - startCountdown(); - } - }); - }); - }); - case 'senpai': - schoolIntro(doof); - case 'roses': - FlxG.sound.play(Paths.sound('ANGRY')); - schoolIntro(doof); - case 'thorns': - schoolIntro(doof); - default: - startCountdown(); - } - } - else - { - switch (curSong.toLowerCase()) - { - default: - startCountdown(); - } - } - - super.create(); - } - - function schoolIntro(?dialogueBox:DialogueBox):Void - { - var black:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); - black.scrollFactor.set(); - add(black); - - var red:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, 0xFFff1b31); - red.scrollFactor.set(); - - var senpaiEvil:FlxSprite = new FlxSprite(); - senpaiEvil.frames = Paths.getSparrowAtlas('weeb/senpaiCrazy'); - senpaiEvil.animation.addByPrefix('idle', 'Senpai Pre Explosion', 24, false); - senpaiEvil.setGraphicSize(Std.int(senpaiEvil.width * 6)); - senpaiEvil.scrollFactor.set(); - senpaiEvil.updateHitbox(); - senpaiEvil.screenCenter(); - - if (SONG.song.toLowerCase() == 'roses' || SONG.song.toLowerCase() == 'thorns') - { - remove(black); - - if (SONG.song.toLowerCase() == 'thorns') - { - add(red); - } - } - - new FlxTimer().start(0.3, function(tmr:FlxTimer) - { - black.alpha -= 0.15; - - if (black.alpha > 0) - { - tmr.reset(0.3); - } - else - { - if (dialogueBox != null) - { - inCutscene = true; - - if (SONG.song.toLowerCase() == 'thorns') - { - add(senpaiEvil); - senpaiEvil.alpha = 0; - new FlxTimer().start(0.3, function(swagTimer:FlxTimer) - { - senpaiEvil.alpha += 0.15; - if (senpaiEvil.alpha < 1) - { - swagTimer.reset(); - } - else - { - senpaiEvil.animation.play('idle'); - FlxG.sound.play(Paths.sound('Senpai_Dies'), 1, false, null, true, function() - { - remove(senpaiEvil); - remove(red); - FlxG.camera.fade(FlxColor.WHITE, 0.01, true, function() - { - add(dialogueBox); - }, true); - }); - new FlxTimer().start(3.2, function(deadTime:FlxTimer) - { - FlxG.camera.fade(FlxColor.WHITE, 1.6, false); - }); - } - }); - } - else - { - add(dialogueBox); - } - } - else - startCountdown(); - - remove(black); - } - }); - } - - var startTimer:FlxTimer; - var perfectMode:Bool = false; - - function startCountdown():Void - { - inCutscene = false; - - generateStaticArrows(0); - generateStaticArrows(1); - - talking = false; - startedCountdown = true; - Conductor.songPosition = 0; - Conductor.songPosition -= Conductor.crochet * 5; - - var swagCounter:Int = 0; - - startTimer = new FlxTimer().start(Conductor.crochet / 1000, function(tmr:FlxTimer) - { - dad.dance(); - gf.dance(); - boyfriend.playAnim('idle'); - - var introAssets:Map> = new Map>(); - introAssets.set('default', ['ready', "set", "go"]); - introAssets.set('school', ['weeb/pixelUI/ready-pixel', 'weeb/pixelUI/set-pixel', 'weeb/pixelUI/date-pixel']); - introAssets.set('schoolEvil', ['weeb/pixelUI/ready-pixel', 'weeb/pixelUI/set-pixel', 'weeb/pixelUI/date-pixel']); - - var introAlts:Array = introAssets.get('default'); - var altSuffix:String = ""; - - for (value in introAssets.keys()) - { - if (value == curStage) - { - introAlts = introAssets.get(value); - altSuffix = '-pixel'; - } - } - - switch (swagCounter) - - { - case 0: - FlxG.sound.play(Paths.sound('intro3'), 0.6); - case 1: - var ready:FlxSprite = new FlxSprite().loadGraphic(Paths.image(introAlts[0])); - ready.scrollFactor.set(); - ready.updateHitbox(); - - if (curStage.startsWith('school')) - ready.setGraphicSize(Std.int(ready.width * daPixelZoom)); - - ready.screenCenter(); - add(ready); - FlxTween.tween(ready, {y: ready.y += 100, alpha: 0}, Conductor.crochet / 1000, { - ease: FlxEase.cubeInOut, - onComplete: function(twn:FlxTween) - { - ready.destroy(); - } - }); - FlxG.sound.play(Paths.sound('intro2'), 0.6); - case 2: - var set:FlxSprite = new FlxSprite().loadGraphic(Paths.image(introAlts[1])); - set.scrollFactor.set(); - - if (curStage.startsWith('school')) - set.setGraphicSize(Std.int(set.width * daPixelZoom)); - - set.screenCenter(); - add(set); - FlxTween.tween(set, {y: set.y += 100, alpha: 0}, Conductor.crochet / 1000, { - ease: FlxEase.cubeInOut, - onComplete: function(twn:FlxTween) - { - set.destroy(); - } - }); - FlxG.sound.play(Paths.sound('intro1'), 0.6); - case 3: - var go:FlxSprite = new FlxSprite().loadGraphic(Paths.image(introAlts[2])); - go.scrollFactor.set(); - - if (curStage.startsWith('school')) - go.setGraphicSize(Std.int(go.width * daPixelZoom)); - - go.updateHitbox(); - - go.screenCenter(); - add(go); - FlxTween.tween(go, {y: go.y += 100, alpha: 0}, Conductor.crochet / 1000, { - ease: FlxEase.cubeInOut, - onComplete: function(twn:FlxTween) - { - go.destroy(); - } - }); - FlxG.sound.play(Paths.sound('introGo'), 0.6); - case 4: - } - - swagCounter += 1; - // generateSong('fresh'); - }, 5); - } - - var previousFrameTime:Int = 0; - var lastReportedPlayheadPosition:Int = 0; - var songTime:Float = 0; - - function startSong():Void - { - startingSong = false; - - previousFrameTime = FlxG.game.ticks; - lastReportedPlayheadPosition = 0; - - if (!paused) - FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false); - FlxG.sound.music.onComplete = endSong; - vocals.play(); - - #if desktop - // Song duration in a float, useful for the time left feature - songLength = FlxG.sound.music.length; - - // Updating Discord Rich Presence (with Time Left) - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength); - #end - } - - var debugNum:Int = 0; - - private function generateSong(dataPath:String):Void - { - // FlxG.log.add(ChartParser.parse()); - - var songData = SONG; - Conductor.changeBPM(songData.bpm); - - curSong = songData.song; - - if (SONG.needsVoices) - vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song)); - else - vocals = new FlxSound(); - - FlxG.sound.list.add(vocals); - - notes = new FlxTypedGroup(); - add(notes); - - var noteData:Array; - - // NEW SHIT - noteData = songData.notes; - - var playerCounter:Int = 0; - - var daBeats:Int = 0; // Not exactly representative of 'daBeats' lol, just how much it has looped - for (section in noteData) - { - var coolSection:Int = Std.int(section.lengthInSteps / 4); - - for (songNotes in section.sectionNotes) - { - var daStrumTime:Float = songNotes[0]; - var daNoteData:Int = Std.int(songNotes[1] % 4); - - var gottaHitNote:Bool = section.mustHitSection; - - if (songNotes[1] > 3) - { - gottaHitNote = !section.mustHitSection; - } - - var oldNote:Note; - if (unspawnNotes.length > 0) - oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)]; - else - oldNote = null; - - var swagNote:Note = new Note(daStrumTime, daNoteData, oldNote); - swagNote.sustainLength = songNotes[2]; - swagNote.scrollFactor.set(0, 0); - - var susLength:Float = swagNote.sustainLength; - - susLength = susLength / Conductor.stepCrochet; - unspawnNotes.push(swagNote); - - for (susNote in 0...Math.floor(susLength)) - { - oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)]; - - var sustainNote:Note = new Note(daStrumTime + (Conductor.stepCrochet * susNote) + Conductor.stepCrochet, daNoteData, oldNote, true); - sustainNote.scrollFactor.set(); - unspawnNotes.push(sustainNote); - - sustainNote.mustPress = gottaHitNote; - - if (sustainNote.mustPress) - { - sustainNote.x += FlxG.width / 2; // general offset - } - } - - swagNote.mustPress = gottaHitNote; - - if (swagNote.mustPress) - { - swagNote.x += FlxG.width / 2; // general offset - } - else {} - } - daBeats += 1; - } - - // trace(unspawnNotes.length); - // playerCounter += 1; - - unspawnNotes.sort(sortByShit); - - generatedMusic = true; - } - - function sortByShit(Obj1:Note, Obj2:Note):Int - { - return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime); - } - - private function generateStaticArrows(player:Int):Void - { - for (i in 0...4) - { - // FlxG.log.add(i); - var babyArrow:FlxSprite = new FlxSprite(0, strumLine.y); - - switch (curStage) - { - case 'school' | 'schoolEvil': - babyArrow.loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17); - babyArrow.animation.add('green', [6]); - babyArrow.animation.add('red', [7]); - babyArrow.animation.add('blue', [5]); - babyArrow.animation.add('purplel', [4]); - - babyArrow.setGraphicSize(Std.int(babyArrow.width * daPixelZoom)); - babyArrow.updateHitbox(); - babyArrow.antialiasing = false; - - switch (Math.abs(i)) - { - case 0: - babyArrow.x += Note.swagWidth * 0; - babyArrow.animation.add('static', [0]); - babyArrow.animation.add('pressed', [4, 8], 12, false); - babyArrow.animation.add('confirm', [12, 16], 24, false); - case 1: - babyArrow.x += Note.swagWidth * 1; - babyArrow.animation.add('static', [1]); - babyArrow.animation.add('pressed', [5, 9], 12, false); - babyArrow.animation.add('confirm', [13, 17], 24, false); - case 2: - babyArrow.x += Note.swagWidth * 2; - babyArrow.animation.add('static', [2]); - babyArrow.animation.add('pressed', [6, 10], 12, false); - babyArrow.animation.add('confirm', [14, 18], 12, false); - case 3: - babyArrow.x += Note.swagWidth * 3; - babyArrow.animation.add('static', [3]); - babyArrow.animation.add('pressed', [7, 11], 12, false); - babyArrow.animation.add('confirm', [15, 19], 24, false); - } - - default: - babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets'); - babyArrow.animation.addByPrefix('green', 'arrowUP'); - babyArrow.animation.addByPrefix('blue', 'arrowDOWN'); - babyArrow.animation.addByPrefix('purple', 'arrowLEFT'); - babyArrow.animation.addByPrefix('red', 'arrowRIGHT'); - - babyArrow.antialiasing = true; - babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7)); - - switch (Math.abs(i)) - { - case 0: - babyArrow.x += Note.swagWidth * 0; - babyArrow.animation.addByPrefix('static', 'arrowLEFT'); - babyArrow.animation.addByPrefix('pressed', 'left press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false); - case 1: - babyArrow.x += Note.swagWidth * 1; - babyArrow.animation.addByPrefix('static', 'arrowDOWN'); - babyArrow.animation.addByPrefix('pressed', 'down press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false); - case 2: - babyArrow.x += Note.swagWidth * 2; - babyArrow.animation.addByPrefix('static', 'arrowUP'); - babyArrow.animation.addByPrefix('pressed', 'up press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false); - case 3: - babyArrow.x += Note.swagWidth * 3; - babyArrow.animation.addByPrefix('static', 'arrowRIGHT'); - babyArrow.animation.addByPrefix('pressed', 'right press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false); - } - } - - babyArrow.updateHitbox(); - babyArrow.scrollFactor.set(); - - if (!isStoryMode) - { - babyArrow.y -= 10; - babyArrow.alpha = 0; - FlxTween.tween(babyArrow, {y: babyArrow.y + 10, alpha: 1}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * i)}); - } - - babyArrow.ID = i; - - if (player == 1) - { - playerStrums.add(babyArrow); - } - - babyArrow.animation.play('static'); - babyArrow.x += 50; - babyArrow.x += ((FlxG.width / 2) * player); - - strumLineNotes.add(babyArrow); - } - } - - function tweenCamIn():Void - { - FlxTween.tween(FlxG.camera, {zoom: 1.3}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut}); - } - - override function openSubState(SubState:FlxSubState) - { - if (paused) - { - if (FlxG.sound.music != null) - { - FlxG.sound.music.pause(); - vocals.pause(); - } - - if (!startTimer.finished) - startTimer.active = false; - } - - super.openSubState(SubState); - } - - override function closeSubState() - { - if (paused) - { - if (FlxG.sound.music != null && !startingSong) - { - resyncVocals(); - } - - if (!startTimer.finished) - startTimer.active = true; - paused = false; - - #if desktop - if (startTimer.finished) - { - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength - Conductor.songPosition); - } - else - { - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); - } - #end - } - - super.closeSubState(); - } - - override public function onFocus():Void - { - #if desktop - if (health > 0 && !paused) - { - if (Conductor.songPosition > 0.0) - { - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength - Conductor.songPosition); - } - else - { - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); - } - } - #end - - super.onFocus(); - } - - override public function onFocusLost():Void - { - #if desktop - if (health > 0 && !paused) - { - DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); - } - #end - - super.onFocusLost(); - } - - function resyncVocals():Void - { - vocals.pause(); - - FlxG.sound.music.play(); - Conductor.songPosition = FlxG.sound.music.time; - vocals.time = Conductor.songPosition; - vocals.play(); - } - - private var paused:Bool = false; - var startedCountdown:Bool = false; - var canPause:Bool = true; - - override public function update(elapsed:Float) - { - #if !debug - perfectMode = false; - #end - - if (FlxG.keys.justPressed.NINE) - { - if (iconP1.animation.curAnim.name == 'bf-old') - iconP1.animation.play(SONG.player1); - else - iconP1.animation.play('bf-old'); - } - - switch (curStage) - { - case 'philly': - if (trainMoving) - { - trainFrameTiming += elapsed; - - if (trainFrameTiming >= 1 / 24) - { - updateTrainPos(); - trainFrameTiming = 0; - } - } - // phillyCityLights.members[curLight].alpha -= (Conductor.crochet / 1000) * FlxG.elapsed; - } - - super.update(elapsed); - - scoreTxt.text = "Score:" + songScore; - - if (FlxG.keys.justPressed.ENTER && startedCountdown && canPause) - { - persistentUpdate = false; - persistentDraw = true; - paused = true; - - // 1 / 1000 chance for Gitaroo Man easter egg - if (FlxG.random.bool(0.1)) - { - // gitaroo man easter egg - FlxG.switchState(new GitarooPause()); - } - else - openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); - - #if desktop - DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); - #end - } - - if (FlxG.keys.justPressed.SEVEN) - { - FlxG.switchState(new ChartingState()); - - #if desktop - DiscordClient.changePresence("Chart Editor", null, null, true); - #end - } - - // FlxG.watch.addQuick('VOL', vocals.amplitudeLeft); - // FlxG.watch.addQuick('VOLRight', vocals.amplitudeRight); - - iconP1.setGraphicSize(Std.int(FlxMath.lerp(150, iconP1.width, 0.50))); - iconP2.setGraphicSize(Std.int(FlxMath.lerp(150, iconP2.width, 0.50))); - - iconP1.updateHitbox(); - iconP2.updateHitbox(); - - var iconOffset:Int = 26; - - iconP1.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01) - iconOffset); - iconP2.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01)) - (iconP2.width - iconOffset); - - if (health > 2) - health = 2; - - if (healthBar.percent < 20) - iconP1.animation.curAnim.curFrame = 1; - else - iconP1.animation.curAnim.curFrame = 0; - - if (healthBar.percent > 80) - iconP2.animation.curAnim.curFrame = 1; - else - iconP2.animation.curAnim.curFrame = 0; - - /* if (FlxG.keys.justPressed.NINE) - FlxG.switchState(new Charting()); */ - - #if debug - if (FlxG.keys.justPressed.EIGHT) - FlxG.switchState(new AnimationDebug(SONG.player2)); - #end - - if (startingSong) - { - if (startedCountdown) - { - Conductor.songPosition += FlxG.elapsed * 1000; - if (Conductor.songPosition >= 0) - startSong(); - } - } - else - { - // Conductor.songPosition = FlxG.sound.music.time; - Conductor.songPosition += FlxG.elapsed * 1000; - - if (!paused) - { - songTime += FlxG.game.ticks - previousFrameTime; - previousFrameTime = FlxG.game.ticks; - - // Interpolation type beat - if (Conductor.lastSongPos != Conductor.songPosition) - { - songTime = (songTime + Conductor.songPosition) / 2; - Conductor.lastSongPos = Conductor.songPosition; - // Conductor.songPosition += FlxG.elapsed * 1000; - // trace('MISSED FRAME'); - } - } - - // Conductor.lastSongPos = FlxG.sound.music.time; - } - - if (generatedMusic && PlayState.SONG.notes[Std.int(curStep / 16)] != null) - { - if (curBeat % 4 == 0) - { - // trace(PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection); - } - - if (camFollow.x != dad.getMidpoint().x + 150 && !PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection) - { - camFollow.setPosition(dad.getMidpoint().x + 150, dad.getMidpoint().y - 100); - // camFollow.setPosition(lucky.getMidpoint().x - 120, lucky.getMidpoint().y + 210); - - switch (dad.curCharacter) - { - case 'mom': - camFollow.y = dad.getMidpoint().y; - case 'senpai': - camFollow.y = dad.getMidpoint().y - 430; - camFollow.x = dad.getMidpoint().x - 100; - case 'senpai-angry': - camFollow.y = dad.getMidpoint().y - 430; - camFollow.x = dad.getMidpoint().x - 100; - } - - if (dad.curCharacter == 'mom') - vocals.volume = 1; - - if (SONG.song.toLowerCase() == 'tutorial') - { - tweenCamIn(); - } - } - - if (PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection && camFollow.x != boyfriend.getMidpoint().x - 100) - { - camFollow.setPosition(boyfriend.getMidpoint().x - 100, boyfriend.getMidpoint().y - 100); - - switch (curStage) - { - case 'limo': - camFollow.x = boyfriend.getMidpoint().x - 300; - case 'mall': - camFollow.y = boyfriend.getMidpoint().y - 200; - case 'school': - camFollow.x = boyfriend.getMidpoint().x - 200; - camFollow.y = boyfriend.getMidpoint().y - 200; - case 'schoolEvil': - camFollow.x = boyfriend.getMidpoint().x - 200; - camFollow.y = boyfriend.getMidpoint().y - 200; - } - - if (SONG.song.toLowerCase() == 'tutorial') - { - FlxTween.tween(FlxG.camera, {zoom: 1}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut}); - } - } - } - - if (camZooming) - { - FlxG.camera.zoom = FlxMath.lerp(defaultCamZoom, FlxG.camera.zoom, 0.95); - camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, 0.95); - } - - FlxG.watch.addQuick("beatShit", curBeat); - FlxG.watch.addQuick("stepShit", curStep); - - if (curSong == 'Fresh') - { - switch (curBeat) - { - case 16: - camZooming = true; - gfSpeed = 2; - case 48: - gfSpeed = 1; - case 80: - gfSpeed = 2; - case 112: - gfSpeed = 1; - case 163: - // FlxG.sound.music.stop(); - // FlxG.switchState(new TitleState()); - } - } - - if (curSong == 'Bopeebo') - { - switch (curBeat) - { - case 128, 129, 130: - vocals.volume = 0; - // FlxG.sound.music.stop(); - // FlxG.switchState(new PlayState()); - } - } - // better streaming of shit - - // RESET = Quick Game Over Screen - if (controls.RESET) - { - health = 0; - trace("RESET = True"); - } - - // CHEAT = brandon's a pussy - if (controls.CHEAT) - { - health += 1; - trace("User is cheating!"); - } - - if (health <= 0) - { - boyfriend.stunned = true; - - persistentUpdate = false; - persistentDraw = false; - paused = true; - - vocals.stop(); - FlxG.sound.music.stop(); - - openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); - - // FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); - - #if desktop - // Game Over doesn't get his own variable because it's only used here - DiscordClient.changePresence("Game Over - " + detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); - #end - } - - if (unspawnNotes[0] != null) - { - if (unspawnNotes[0].strumTime - Conductor.songPosition < 1500) - { - var dunceNote:Note = unspawnNotes[0]; - notes.add(dunceNote); - - var index:Int = unspawnNotes.indexOf(dunceNote); - unspawnNotes.splice(index, 1); - } - } - - if (generatedMusic) - { - notes.forEachAlive(function(daNote:Note) - { - if (daNote.y > FlxG.height) - { - daNote.active = false; - daNote.visible = false; - } - else - { - daNote.visible = true; - daNote.active = true; - } - - daNote.y = (strumLine.y - (Conductor.songPosition - daNote.strumTime) * (0.45 * FlxMath.roundDecimal(SONG.speed, 2))); - - // i am so fucking sorry for this if condition - if (daNote.isSustainNote - && daNote.y + daNote.offset.y <= strumLine.y + Note.swagWidth / 2 - && (!daNote.mustPress || (daNote.wasGoodHit || (daNote.prevNote.wasGoodHit && !daNote.canBeHit)))) - { - var swagRect = new FlxRect(0, strumLine.y + Note.swagWidth / 2 - daNote.y, daNote.width * 2, daNote.height * 2); - swagRect.y /= daNote.scale.y; - swagRect.height -= swagRect.y; - - daNote.clipRect = swagRect; - } - - if (!daNote.mustPress && daNote.wasGoodHit) - { - if (SONG.song != 'Tutorial') - camZooming = true; - - var altAnim:String = ""; - - if (SONG.notes[Math.floor(curStep / 16)] != null) - { - if (SONG.notes[Math.floor(curStep / 16)].altAnim) - altAnim = '-alt'; - } - - switch (Math.abs(daNote.noteData)) - { - case 0: - dad.playAnim('singLEFT' + altAnim, true); - case 1: - dad.playAnim('singDOWN' + altAnim, true); - case 2: - dad.playAnim('singUP' + altAnim, true); - case 3: - dad.playAnim('singRIGHT' + altAnim, true); - } - - dad.holdTimer = 0; - - if (SONG.needsVoices) - vocals.volume = 1; - - daNote.kill(); - notes.remove(daNote, true); - daNote.destroy(); - } - - // WIP interpolation shit? Need to fix the pause issue - // daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed)); - - if (daNote.y < -daNote.height) - { - if (daNote.tooLate || !daNote.wasGoodHit) - { - health -= 0.0475; - vocals.volume = 0; - } - - daNote.active = false; - daNote.visible = false; - - daNote.kill(); - notes.remove(daNote, true); - daNote.destroy(); - } - }); - } - - if (!inCutscene) - keyShit(); - - #if debug - if (FlxG.keys.justPressed.ONE) - endSong(); - #end - } - - function endSong():Void - { - canPause = false; - FlxG.sound.music.volume = 0; - vocals.volume = 0; - if (SONG.validScore) - { - #if !switch - Highscore.saveScore(SONG.song, songScore, storyDifficulty); - #end - } - - if (isStoryMode) - { - campaignScore += songScore; - - storyPlaylist.remove(storyPlaylist[0]); - - if (storyPlaylist.length <= 0) - { - FlxG.sound.playMusic(Paths.music('freakyMenu')); - - transIn = FlxTransitionableState.defaultTransIn; - transOut = FlxTransitionableState.defaultTransOut; - - FlxG.switchState(new StoryMenuState()); - - // if () - StoryMenuState.weekUnlocked[Std.int(Math.min(storyWeek + 1, StoryMenuState.weekUnlocked.length - 1))] = true; - - if (SONG.validScore) - { - Highscore.saveWeekScore(storyWeek, campaignScore, storyDifficulty); - } - - FlxG.save.data.weekUnlocked = StoryMenuState.weekUnlocked; - FlxG.save.flush(); - } - else - { - var difficulty:String = ""; - - if (storyDifficulty == 0) - difficulty = '-easy'; - - if (storyDifficulty == 2) - difficulty = '-hard'; - - trace('LOADING NEXT SONG'); - trace(PlayState.storyPlaylist[0].toLowerCase() + difficulty); - - if (SONG.song.toLowerCase() == 'eggnog') - { - var blackShit:FlxSprite = new FlxSprite(-FlxG.width * FlxG.camera.zoom, - -FlxG.height * FlxG.camera.zoom).makeGraphic(FlxG.width * 3, FlxG.height * 3, FlxColor.BLACK); - blackShit.scrollFactor.set(); - add(blackShit); - camHUD.visible = false; - - FlxG.sound.play(Paths.sound('Lights_Shut_off')); - } - - FlxTransitionableState.skipNextTransIn = true; - FlxTransitionableState.skipNextTransOut = true; - prevCamFollow = camFollow; - - PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + difficulty, PlayState.storyPlaylist[0]); - FlxG.sound.music.stop(); - - LoadingState.loadAndSwitchState(new PlayState()); - } - } - else - { - trace('WENT BACK TO FREEPLAY??'); - FlxG.switchState(new FreeplayState()); - } - } - - var endingSong:Bool = false; - - private function popUpScore(strumtime:Float):Void - { - var noteDiff:Float = Math.abs(strumtime - Conductor.songPosition); - // boyfriend.playAnim('hey'); - vocals.volume = 1; - - var placement:String = Std.string(combo); - - var coolText:FlxText = new FlxText(0, 0, 0, placement, 32); - coolText.screenCenter(); - coolText.x = FlxG.width * 0.55; - // - - var rating:FlxSprite = new FlxSprite(); - var score:Int = 350; - - var daRating:String = "sick"; - - if (noteDiff > Conductor.safeZoneOffset * 0.9) - { - daRating = 'shit'; - score = 50; - } - else if (noteDiff > Conductor.safeZoneOffset * 0.75) - { - daRating = 'bad'; - score = 100; - } - else if (noteDiff > Conductor.safeZoneOffset * 0.2) - { - daRating = 'good'; - score = 200; - } - - songScore += score; - - /* if (combo > 60) - daRating = 'sick'; - else if (combo > 12) - daRating = 'good' - else if (combo > 4) - daRating = 'bad'; - */ - - var pixelShitPart1:String = ""; - var pixelShitPart2:String = ''; - - if (curStage.startsWith('school')) - { - pixelShitPart1 = 'weeb/pixelUI/'; - pixelShitPart2 = '-pixel'; - } - - rating.loadGraphic(Paths.image(pixelShitPart1 + daRating + pixelShitPart2)); - rating.screenCenter(); - rating.x = coolText.x - 40; - rating.y -= 60; - rating.acceleration.y = 550; - rating.velocity.y -= FlxG.random.int(140, 175); - rating.velocity.x -= FlxG.random.int(0, 10); - - var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); - comboSpr.screenCenter(); - comboSpr.x = coolText.x; - comboSpr.acceleration.y = 600; - comboSpr.velocity.y -= 150; - - comboSpr.velocity.x += FlxG.random.int(1, 10); - add(rating); - - if (!curStage.startsWith('school')) - { - rating.setGraphicSize(Std.int(rating.width * 0.7)); - rating.antialiasing = true; - comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7)); - comboSpr.antialiasing = true; - } - else - { - rating.setGraphicSize(Std.int(rating.width * daPixelZoom * 0.7)); - comboSpr.setGraphicSize(Std.int(comboSpr.width * daPixelZoom * 0.7)); - } - - comboSpr.updateHitbox(); - rating.updateHitbox(); - - var seperatedScore:Array = []; - - seperatedScore.push(Math.floor(combo / 100)); - seperatedScore.push(Math.floor((combo - (seperatedScore[0] * 100)) / 10)); - seperatedScore.push(combo % 10); - - var daLoop:Int = 0; - for (i in seperatedScore) - { - var numScore:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2)); - numScore.screenCenter(); - numScore.x = coolText.x + (43 * daLoop) - 90; - numScore.y += 80; - - if (!curStage.startsWith('school')) - { - numScore.antialiasing = true; - numScore.setGraphicSize(Std.int(numScore.width * 0.5)); - } - else - { - numScore.setGraphicSize(Std.int(numScore.width * daPixelZoom)); - } - numScore.updateHitbox(); - - numScore.acceleration.y = FlxG.random.int(200, 300); - numScore.velocity.y -= FlxG.random.int(140, 160); - numScore.velocity.x = FlxG.random.float(-5, 5); - - if (combo >= 10 || combo == 0) - add(numScore); - - FlxTween.tween(numScore, {alpha: 0}, 0.2, { - onComplete: function(tween:FlxTween) - { - numScore.destroy(); - }, - startDelay: Conductor.crochet * 0.002 - }); - - daLoop++; - } - /* - trace(combo); - trace(seperatedScore); - */ - - coolText.text = Std.string(seperatedScore); - // add(coolText); - - FlxTween.tween(rating, {alpha: 0}, 0.2, { - startDelay: Conductor.crochet * 0.001 - }); - - FlxTween.tween(comboSpr, {alpha: 0}, 0.2, { - onComplete: function(tween:FlxTween) - { - coolText.destroy(); - comboSpr.destroy(); - - rating.destroy(); - }, - startDelay: Conductor.crochet * 0.001 - }); - - curSection += 1; - } - - private function keyShit():Void - { - // HOLDING - var up = controls.UP; - var right = controls.RIGHT; - var down = controls.DOWN; - var left = controls.LEFT; - - var upP = controls.UP_P; - var rightP = controls.RIGHT_P; - var downP = controls.DOWN_P; - var leftP = controls.LEFT_P; - - var upR = controls.UP_R; - var rightR = controls.RIGHT_R; - var downR = controls.DOWN_R; - var leftR = controls.LEFT_R; - - var controlArray:Array = [leftP, downP, upP, rightP]; - - // FlxG.watch.addQuick('asdfa', upP); - if ((upP || rightP || downP || leftP) && !boyfriend.stunned && generatedMusic) - { - boyfriend.holdTimer = 0; - - var possibleNotes:Array = []; - - var ignoreList:Array = []; - - notes.forEachAlive(function(daNote:Note) - { - if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit) - { - // the sorting probably doesn't need to be in here? who cares lol - possibleNotes.push(daNote); - possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime)); - - ignoreList.push(daNote.noteData); - } - }); - - if (possibleNotes.length > 0) - { - var daNote = possibleNotes[0]; - - if (perfectMode) - noteCheck(true, daNote); - - // Jump notes - if (possibleNotes.length >= 2) - { - if (possibleNotes[0].strumTime == possibleNotes[1].strumTime) - { - for (coolNote in possibleNotes) - { - if (controlArray[coolNote.noteData]) - goodNoteHit(coolNote); - else - { - var inIgnoreList:Bool = false; - for (shit in 0...ignoreList.length) - { - if (controlArray[ignoreList[shit]]) - inIgnoreList = true; - } - if (!inIgnoreList) - badNoteCheck(); - } - } - } - else if (possibleNotes[0].noteData == possibleNotes[1].noteData) - { - noteCheck(controlArray[daNote.noteData], daNote); - } - else - { - for (coolNote in possibleNotes) - { - noteCheck(controlArray[coolNote.noteData], coolNote); - } - } - } - else // regular notes? - { - noteCheck(controlArray[daNote.noteData], daNote); - } - /* - if (controlArray[daNote.noteData]) - goodNoteHit(daNote); - */ - // trace(daNote.noteData); - /* - switch (daNote.noteData) - { - case 2: // NOTES YOU JUST PRESSED - if (upP || rightP || downP || leftP) - noteCheck(upP, daNote); - case 3: - if (upP || rightP || downP || leftP) - noteCheck(rightP, daNote); - case 1: - if (upP || rightP || downP || leftP) - noteCheck(downP, daNote); - case 0: - if (upP || rightP || downP || leftP) - noteCheck(leftP, daNote); - } - - //this is already done in noteCheck / goodNoteHit - if (daNote.wasGoodHit) - { - daNote.kill(); - notes.remove(daNote, true); - daNote.destroy(); - } - */ - } - else - { - badNoteCheck(); - } - } - - if ((up || right || down || left) && !boyfriend.stunned && generatedMusic) - { - notes.forEachAlive(function(daNote:Note) - { - if (daNote.canBeHit && daNote.mustPress && daNote.isSustainNote) - { - switch (daNote.noteData) - { - // NOTES YOU ARE HOLDING - case 0: - if (left) - goodNoteHit(daNote); - case 1: - if (down) - goodNoteHit(daNote); - case 2: - if (up) - goodNoteHit(daNote); - case 3: - if (right) - goodNoteHit(daNote); - } - } - }); - } - - if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && !up && !down && !right && !left) - { - if (boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss')) - { - boyfriend.playAnim('idle'); - } - } - - playerStrums.forEach(function(spr:FlxSprite) - { - switch (spr.ID) - { - case 0: - if (leftP && spr.animation.curAnim.name != 'confirm') - spr.animation.play('pressed'); - if (leftR) - spr.animation.play('static'); - case 1: - if (downP && spr.animation.curAnim.name != 'confirm') - spr.animation.play('pressed'); - if (downR) - spr.animation.play('static'); - case 2: - if (upP && spr.animation.curAnim.name != 'confirm') - spr.animation.play('pressed'); - if (upR) - spr.animation.play('static'); - case 3: - if (rightP && spr.animation.curAnim.name != 'confirm') - spr.animation.play('pressed'); - if (rightR) - spr.animation.play('static'); - } - - if (spr.animation.curAnim.name == 'confirm' && !curStage.startsWith('school')) - { - spr.centerOffsets(); - spr.offset.x -= 13; - spr.offset.y -= 13; - } - else - spr.centerOffsets(); - }); - } - - function noteMiss(direction:Int = 1):Void - { - if (!boyfriend.stunned) - { - health -= 0.04; - if (combo > 5 && gf.animOffsets.exists('sad')) - { - gf.playAnim('sad'); - } - combo = 0; - - songScore -= 10; - - FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); - // FlxG.sound.play(Paths.sound('missnote1'), 1, false); - // FlxG.log.add('played imss note'); - - boyfriend.stunned = true; - - // get stunned for 5 seconds - new FlxTimer().start(5 / 60, function(tmr:FlxTimer) - { - boyfriend.stunned = false; - }); - - switch (direction) - { - case 0: - boyfriend.playAnim('singLEFTmiss', true); - case 1: - boyfriend.playAnim('singDOWNmiss', true); - case 2: - boyfriend.playAnim('singUPmiss', true); - case 3: - boyfriend.playAnim('singRIGHTmiss', true); - } - } - } - - function badNoteCheck() - { - // just double pasting this shit cuz fuk u - // REDO THIS SYSTEM! - var upP = controls.UP_P; - var rightP = controls.RIGHT_P; - var downP = controls.DOWN_P; - var leftP = controls.LEFT_P; - - if (leftP) - noteMiss(0); - if (downP) - noteMiss(1); - if (upP) - noteMiss(2); - if (rightP) - noteMiss(3); - } - - function noteCheck(keyP:Bool, note:Note):Void - { - if (keyP) - goodNoteHit(note); - else - { - badNoteCheck(); - } - } - - function goodNoteHit(note:Note):Void - { - if (!note.wasGoodHit) - { - if (!note.isSustainNote) - { - popUpScore(note.strumTime); - combo += 1; - } - - if (note.noteData >= 0) - health += 0.023; - else - health += 0.004; - - switch (note.noteData) - { - case 0: - boyfriend.playAnim('singLEFT', true); - case 1: - boyfriend.playAnim('singDOWN', true); - case 2: - boyfriend.playAnim('singUP', true); - case 3: - boyfriend.playAnim('singRIGHT', true); - } - - playerStrums.forEach(function(spr:FlxSprite) - { - if (Math.abs(note.noteData) == spr.ID) - { - spr.animation.play('confirm', true); - } - }); - - note.wasGoodHit = true; - vocals.volume = 1; - - if (!note.isSustainNote) - { - note.kill(); - notes.remove(note, true); - note.destroy(); - } - } - } - - var fastCarCanDrive:Bool = true; - - function resetFastCar():Void - { - fastCar.x = -12600; - fastCar.y = FlxG.random.int(140, 250); - fastCar.velocity.x = 0; - fastCarCanDrive = true; - } - - function fastCarDrive() - { - FlxG.sound.play(Paths.soundRandom('carPass', 0, 1), 0.7); - - fastCar.velocity.x = (FlxG.random.int(170, 220) / FlxG.elapsed) * 3; - fastCarCanDrive = false; - new FlxTimer().start(2, function(tmr:FlxTimer) - { - resetFastCar(); - }); - } - - var trainMoving:Bool = false; - var trainFrameTiming:Float = 0; - - var trainCars:Int = 8; - var trainFinishing:Bool = false; - var trainCooldown:Int = 0; - - function trainStart():Void - { - trainMoving = true; - if (!trainSound.playing) - trainSound.play(true); - } - - var startedMoving:Bool = false; - - function updateTrainPos():Void - { - if (trainSound.time >= 4700) - { - startedMoving = true; - gf.playAnim('hairBlow'); - } - - if (startedMoving) - { - phillyTrain.x -= 400; - - if (phillyTrain.x < -2000 && !trainFinishing) - { - phillyTrain.x = -1150; - trainCars -= 1; - - if (trainCars <= 0) - trainFinishing = true; - } - - if (phillyTrain.x < -4000 && trainFinishing) - trainReset(); - } - } - - function trainReset():Void - { - gf.playAnim('hairFall'); - phillyTrain.x = FlxG.width + 200; - trainMoving = false; - // trainSound.stop(); - // trainSound.time = 0; - trainCars = 8; - trainFinishing = false; - startedMoving = false; - } - - function lightningStrikeShit():Void - { - FlxG.sound.play(Paths.soundRandom('thunder_', 1, 2)); - halloweenBG.animation.play('lightning'); - - lightningStrikeBeat = curBeat; - lightningOffset = FlxG.random.int(8, 24); - - boyfriend.playAnim('scared', true); - gf.playAnim('scared', true); - } - - override function stepHit() - { - super.stepHit(); - if (FlxG.sound.music.time > Conductor.songPosition + 20 || FlxG.sound.music.time < Conductor.songPosition - 20) - { - resyncVocals(); - } - - if (dad.curCharacter == 'spooky' && curStep % 4 == 2) - { - // dad.dance(); - } - } - - var lightningStrikeBeat:Int = 0; - var lightningOffset:Int = 8; - - override function beatHit() - { - super.beatHit(); - - if (generatedMusic) - { - notes.sort(FlxSort.byY, FlxSort.DESCENDING); - } - - if (SONG.notes[Math.floor(curStep / 16)] != null) - { - if (SONG.notes[Math.floor(curStep / 16)].changeBPM) - { - Conductor.changeBPM(SONG.notes[Math.floor(curStep / 16)].bpm); - FlxG.log.add('CHANGED BPM!'); - } - // else - // Conductor.changeBPM(SONG.bpm); - - // Dad doesnt interupt his own notes - if (SONG.notes[Math.floor(curStep / 16)].mustHitSection) - dad.dance(); - } - // FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM); - wiggleShit.update(Conductor.crochet); - - // HARDCODING FOR MILF ZOOMS! - if (curSong.toLowerCase() == 'milf' && curBeat >= 168 && curBeat < 200 && camZooming && FlxG.camera.zoom < 1.35) - { - FlxG.camera.zoom += 0.015; - camHUD.zoom += 0.03; - } - - if (camZooming && FlxG.camera.zoom < 1.35 && curBeat % 4 == 0) - { - FlxG.camera.zoom += 0.015; - camHUD.zoom += 0.03; - } - - iconP1.setGraphicSize(Std.int(iconP1.width + 30)); - iconP2.setGraphicSize(Std.int(iconP2.width + 30)); - - iconP1.updateHitbox(); - iconP2.updateHitbox(); - - if (curBeat % gfSpeed == 0) - { - gf.dance(); - } - - if (!boyfriend.animation.curAnim.name.startsWith("sing")) - { - boyfriend.playAnim('idle'); - } - - if (curBeat % 8 == 7 && curSong == 'Bopeebo') - { - boyfriend.playAnim('hey', true); - } - - if (curBeat % 16 == 15 && SONG.song == 'Tutorial' && dad.curCharacter == 'gf' && curBeat > 16 && curBeat < 48) - { - boyfriend.playAnim('hey', true); - dad.playAnim('cheer', true); - } - - switch (curStage) - { - case 'school': - bgGirls.dance(); - - case 'mall': - upperBoppers.animation.play('bop', true); - bottomBoppers.animation.play('bop', true); - santa.animation.play('idle', true); - - case 'limo': - grpLimoDancers.forEach(function(dancer:BackgroundDancer) - { - dancer.dance(); - }); - - if (FlxG.random.bool(10) && fastCarCanDrive) - fastCarDrive(); - case "philly": - if (!trainMoving) - trainCooldown += 1; - - if (curBeat % 4 == 0) - { - phillyCityLights.forEach(function(light:FlxSprite) - { - light.visible = false; - }); - - curLight = FlxG.random.int(0, phillyCityLights.length - 1); - - phillyCityLights.members[curLight].visible = true; - // phillyCityLights.members[curLight].alpha = 1; - } - - if (curBeat % 8 == 4 && FlxG.random.bool(30) && !trainMoving && trainCooldown > 8) - { - trainCooldown = FlxG.random.int(-4, 0); - trainStart(); - } - } - - if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset) - { - lightningStrikeShit(); - } - } - - var curLight:Int = 0; -} diff --git a/source/Note.hx b/source/funkin/game/Note.hx similarity index 96% rename from source/Note.hx rename to source/funkin/game/Note.hx index 114a7ffb..68a13428 100644 --- a/source/Note.hx +++ b/source/funkin/game/Note.hx @@ -1,4 +1,4 @@ -package; +package funkin.game; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; @@ -21,6 +21,13 @@ class Note extends FlxSprite public var wasGoodHit:Bool = false; public var prevNote:Note; + public var strumID(get, never):Int; + private function get_strumID() { + var id = noteData % 4; + if (id < 0) id = 0; + return id; + } + public var sustainLength:Float = 0; public var isSustainNote:Bool = false; diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx new file mode 100644 index 00000000..0dd2acfa --- /dev/null +++ b/source/funkin/game/PlayState.hx @@ -0,0 +1,1428 @@ +package funkin.game; + +#if desktop +import Discord.DiscordClient; +#end +import Section.SwagSection; +import Song.SwagSong; +import WiggleEffect.WiggleEffectType; +import flixel.FlxBasic; +import flixel.FlxCamera; +import flixel.FlxG; +import flixel.FlxGame; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.FlxState; +import flixel.FlxSubState; +import flixel.addons.display.FlxGridOverlay; +import flixel.addons.effects.FlxTrail; +import flixel.addons.effects.FlxTrailArea; +import flixel.addons.effects.chainable.FlxEffectSprite; +import flixel.addons.effects.chainable.FlxWaveEffect; +import flixel.addons.transition.FlxTransitionableState; +import flixel.graphics.atlas.FlxAtlas; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.system.FlxSound; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.ui.FlxBar; +import flixel.util.FlxCollision; +import flixel.util.FlxColor; +import flixel.util.FlxSort; +import flixel.util.FlxStringUtil; +import flixel.util.FlxTimer; +import haxe.Json; +import lime.utils.Assets; +import openfl.display.BlendMode; +import openfl.display.StageQuality; +import openfl.filters.ShaderFilter; + +using StringTools; + +class PlayState extends MusicBeatState +{ + public static var curStage:String = ''; + public static var SONG:SwagSong; + public static var isStoryMode:Bool = false; + public static var storyWeek:Int = 0; + public static var storyPlaylist:Array = []; + public static var storyDifficulty:Int = 1; + + var halloweenLevel:Bool = false; + + private var vocals:FlxSound; + + private var dad:Character; + private var gf:Character; + private var boyfriend:Boyfriend; + + private var notes:FlxTypedGroup; + private var unspawnNotes:Array = []; + + private var strumLine:FlxSprite; + private var curSection:Int = 0; + + private var camFollow:FlxObject; + + private static var prevCamFollow:FlxObject; + + private var strumLineNotes:FlxTypedGroup; + private var playerStrums:FlxTypedGroup; + private var cpuStrums:FlxTypedGroup; + + private var camZooming:Bool = false; + private var curSong:String = ""; + + private var gfSpeed:Int = 1; + private var health:Float = 1; + private var combo:Int = 0; + + private var healthBarBG:FlxSprite; + private var healthBar:FlxBar; + + private var generatedMusic:Bool = false; + private var startingSong:Bool = false; + + private var iconP1:HealthIcon; + private var iconP2:HealthIcon; + private var camHUD:FlxCamera; + private var camGame:FlxCamera; + + + var songScore:Int = 0; + var scoreTxt:FlxText; + + public static var campaignScore:Int = 0; + + var defaultCamZoom:Float = 1.05; + + // how big to stretch the pixel art assets + public static var daPixelZoom:Float = 6; + + var inCutscene:Bool = false; + + #if desktop + // Discord RPC variables + var storyDifficultyText:String = ""; + var iconRPC:String = ""; + var songLength:Float = 0; + var detailsText:String = ""; + var detailsPausedText:String = ""; + #end + + override public function create() + { + if (FlxG.sound.music != null) + FlxG.sound.music.stop(); + + camGame = new FlxCamera(); + camHUD = new FlxCamera(); + camHUD.bgColor.alpha = 0; + + FlxG.cameras.reset(camGame); + FlxG.cameras.add(camHUD, false); + + persistentUpdate = true; + persistentDraw = true; + + if (SONG == null) + SONG = Song.loadFromJson('tutorial'); + + Conductor.mapBPMChanges(SONG); + Conductor.changeBPM(SONG.bpm); + + #if desktop + // TODO: Scriptable custom RPC + iconRPC = SONG.player2; + + // String that contains the mode defined here so it isn't necessary to call changePresence for each mode + if (isStoryMode) + { + detailsText = "Story Mode: Week " + storyWeek; + } + else + { + detailsText = "Freeplay"; + } + + // String for when the game is paused + detailsPausedText = "Paused - " + detailsText; + + // Updating Discord Rich Presence. + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + #end + + + // TODO: Chart GF version + gf = new Character(400, 130, "gf"); + gf.scrollFactor.set(0.95, 0.95); + + dad = new Character(100, 100, SONG.player2); + + var camPos:FlxPoint = new FlxPoint(dad.getGraphicMidpoint().x, dad.getGraphicMidpoint().y); + + + boyfriend = new Boyfriend(770, 450, SONG.player1); + + + add(gf); + + // TODO: cool layering 🔥 + + add(dad); + add(boyfriend); + + strumLine = new FlxSprite(0, 50).makeGraphic(FlxG.width, 10); + strumLine.scrollFactor.set(); + + strumLineNotes = new FlxTypedGroup(); + add(strumLineNotes); + + playerStrums = new FlxTypedGroup(); + cpuStrums = new FlxTypedGroup(); + + // startCountdown(); + + generateSong(SONG.song); + + // add(strumLine); + + if (prevCamFollow != null) + { + camFollow = prevCamFollow; + prevCamFollow = null; + } else { + camFollow = new FlxObject(0, 0, 2, 2); + camFollow.setPosition(camPos.x, camPos.y); + } + add(camFollow); + + FlxG.camera.follow(camFollow, LOCKON, 0.04); + FlxG.camera.zoom = defaultCamZoom; + FlxG.camera.focusOn(camFollow.getPosition()); + + FlxG.worldBounds.set(0, 0, FlxG.width, FlxG.height); + + // TODO: cool healthbar + healthBarBG = new FlxSprite(0, FlxG.height * 0.9).loadGraphic(Paths.image('healthBar')); + healthBarBG.screenCenter(X); + healthBarBG.scrollFactor.set(); + add(healthBarBG); + + healthBar = new FlxBar(healthBarBG.x + 4, healthBarBG.y + 4, RIGHT_TO_LEFT, Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, + 'health', 0, 2); + healthBar.scrollFactor.set(); + healthBar.createFilledBar(0xFFFF0000, 0xFF66FF33); + add(healthBar); + + scoreTxt = new FlxText(healthBarBG.x + healthBarBG.width - 190, healthBarBG.y + 30, 0, "", 20); + scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT); + scoreTxt.scrollFactor.set(); + add(scoreTxt); + + iconP1 = new HealthIcon(SONG.player1, true); + iconP1.y = healthBar.y - (iconP1.height / 2); + add(iconP1); + + iconP2 = new HealthIcon(SONG.player2, false); + iconP2.y = healthBar.y - (iconP2.height / 2); + add(iconP2); + + for(e in [strumLineNotes, notes, healthBar, healthBarBG, iconP1, iconP2, scoreTxt]) { + e.cameras = [camHUD]; + } + + startingSong = true; + + super.create(); + } + + public override function createPost() { + super.createPost(); + startCountdown(); + } + + var startTimer:FlxTimer; + var perfectMode:Bool = false; + + function startCountdown():Void + { + inCutscene = false; + + generateStaticArrows(0); + generateStaticArrows(1); + + startedCountdown = true; + Conductor.songPosition = 0; + Conductor.songPosition -= Conductor.crochet * 5; + + var swagCounter:Int = 0; + + startTimer = new FlxTimer().start(Conductor.crochet / 1000, function(tmr:FlxTimer) + { + dad.dance(); + gf.dance(); + boyfriend.playAnim('idle'); + + var introAssets:Map> = new Map>(); + introAssets.set('default', ['ready', "set", "go"]); + introAssets.set('school', ['weeb/pixelUI/ready-pixel', 'weeb/pixelUI/set-pixel', 'weeb/pixelUI/date-pixel']); + introAssets.set('schoolEvil', ['weeb/pixelUI/ready-pixel', 'weeb/pixelUI/set-pixel', 'weeb/pixelUI/date-pixel']); + + var introAlts:Array = introAssets.get('default'); + var altSuffix:String = ""; + + for (value in introAssets.keys()) + { + if (value == curStage) + { + introAlts = introAssets.get(value); + altSuffix = '-pixel'; + } + } + + switch (swagCounter) + + { + case 0: + FlxG.sound.play(Paths.sound('intro3'), 0.6); + case 1: + var ready:FlxSprite = new FlxSprite().loadGraphic(Paths.image(introAlts[0])); + ready.scrollFactor.set(); + ready.updateHitbox(); + + if (curStage.startsWith('school')) + ready.setGraphicSize(Std.int(ready.width * daPixelZoom)); + + ready.screenCenter(); + add(ready); + FlxTween.tween(ready, {y: ready.y += 100, alpha: 0}, Conductor.crochet / 1000, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + ready.destroy(); + } + }); + FlxG.sound.play(Paths.sound('intro2'), 0.6); + case 2: + var set:FlxSprite = new FlxSprite().loadGraphic(Paths.image(introAlts[1])); + set.scrollFactor.set(); + + if (curStage.startsWith('school')) + set.setGraphicSize(Std.int(set.width * daPixelZoom)); + + set.screenCenter(); + add(set); + FlxTween.tween(set, {y: set.y += 100, alpha: 0}, Conductor.crochet / 1000, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + set.destroy(); + } + }); + FlxG.sound.play(Paths.sound('intro1'), 0.6); + case 3: + var go:FlxSprite = new FlxSprite().loadGraphic(Paths.image(introAlts[2])); + go.scrollFactor.set(); + + if (curStage.startsWith('school')) + go.setGraphicSize(Std.int(go.width * daPixelZoom)); + + go.updateHitbox(); + + go.screenCenter(); + add(go); + FlxTween.tween(go, {y: go.y += 100, alpha: 0}, Conductor.crochet / 1000, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + go.destroy(); + } + }); + FlxG.sound.play(Paths.sound('introGo'), 0.6); + case 4: + } + + swagCounter += 1; + // generateSong('fresh'); + }, 5); + } + + var previousFrameTime:Int = 0; + var lastReportedPlayheadPosition:Int = 0; + var songTime:Float = 0; + + function startSong():Void + { + startingSong = false; + + previousFrameTime = FlxG.game.ticks; + lastReportedPlayheadPosition = 0; + + if (!paused) + FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false); + FlxG.sound.music.onComplete = endSong; + vocals.play(); + + updateDiscordStatus(); + } + + var debugNum:Int = 0; + + private function generateSong(dataPath:String):Void + { + // FlxG.log.add(ChartParser.parse()); + + var songData = SONG; + Conductor.changeBPM(songData.bpm); + + curSong = songData.song; + + if (SONG.needsVoices) + vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song)); + else + vocals = new FlxSound(); + + FlxG.sound.list.add(vocals); + + notes = new FlxTypedGroup(); + add(notes); + + var noteData:Array; + + // NEW SHIT + noteData = songData.notes; + + var playerCounter:Int = 0; + + var daBeats:Int = 0; // Not exactly representative of 'daBeats' lol, just how much it has looped + for (section in noteData) + { + var coolSection:Int = Std.int(section.lengthInSteps / 4); + + for (songNotes in section.sectionNotes) + { + var daStrumTime:Float = songNotes[0]; + var daNoteData:Int = Std.int(songNotes[1] % 4); + + var gottaHitNote:Bool = section.mustHitSection; + + if (songNotes[1] > 3) + { + gottaHitNote = !section.mustHitSection; + } + + var oldNote:Note; + if (unspawnNotes.length > 0) + oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)]; + else + oldNote = null; + + var swagNote:Note = new Note(daStrumTime, daNoteData, oldNote); + swagNote.sustainLength = songNotes[2]; + swagNote.scrollFactor.set(0, 0); + + var susLength:Float = swagNote.sustainLength; + + susLength = susLength / Conductor.stepCrochet; + unspawnNotes.push(swagNote); + + for (susNote in 0...Math.floor(susLength)) + { + oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)]; + + var sustainNote:Note = new Note(daStrumTime + (Conductor.stepCrochet * susNote) + Conductor.stepCrochet, daNoteData, oldNote, true); + sustainNote.scrollFactor.set(); + unspawnNotes.push(sustainNote); + + sustainNote.mustPress = gottaHitNote; + + if (sustainNote.mustPress) + { + sustainNote.x += FlxG.width / 2; // general offset + } + } + + swagNote.mustPress = gottaHitNote; + + if (swagNote.mustPress) + { + swagNote.x += FlxG.width / 2; // general offset + } + else {} + } + daBeats += 1; + } + + // trace(unspawnNotes.length); + // playerCounter += 1; + + unspawnNotes.sort(sortByShit); + + generatedMusic = true; + } + + function sortByShit(Obj1:Note, Obj2:Note):Int + { + return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime); + } + + private function generateStaticArrows(player:Int):Void + { + for (i in 0...4) + { + // FlxG.log.add(i); + var babyArrow:Strum = new Strum(0, strumLine.y); + + switch (curStage) + { + case 'school' | 'schoolEvil': + babyArrow.loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17); + babyArrow.animation.add('green', [6]); + babyArrow.animation.add('red', [7]); + babyArrow.animation.add('blue', [5]); + babyArrow.animation.add('purplel', [4]); + + babyArrow.setGraphicSize(Std.int(babyArrow.width * daPixelZoom)); + babyArrow.updateHitbox(); + babyArrow.antialiasing = false; + + switch (Math.abs(i)) + { + case 0: + babyArrow.animation.add('static', [0]); + babyArrow.animation.add('pressed', [4, 8], 12, false); + babyArrow.animation.add('confirm', [12, 16], 24, false); + case 1: + babyArrow.animation.add('static', [1]); + babyArrow.animation.add('pressed', [5, 9], 12, false); + babyArrow.animation.add('confirm', [13, 17], 24, false); + case 2: + babyArrow.animation.add('static', [2]); + babyArrow.animation.add('pressed', [6, 10], 12, false); + babyArrow.animation.add('confirm', [14, 18], 12, false); + case 3: + babyArrow.animation.add('static', [3]); + babyArrow.animation.add('pressed', [7, 11], 12, false); + babyArrow.animation.add('confirm', [15, 19], 24, false); + } + + default: + babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets'); + babyArrow.animation.addByPrefix('green', 'arrowUP'); + babyArrow.animation.addByPrefix('blue', 'arrowDOWN'); + babyArrow.animation.addByPrefix('purple', 'arrowLEFT'); + babyArrow.animation.addByPrefix('red', 'arrowRIGHT'); + + babyArrow.antialiasing = true; + babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7)); + + switch (Math.abs(i)) + { + case 0: + babyArrow.animation.addByPrefix('static', 'arrowLEFT'); + babyArrow.animation.addByPrefix('pressed', 'left press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false); + case 1: + babyArrow.animation.addByPrefix('static', 'arrowDOWN'); + babyArrow.animation.addByPrefix('pressed', 'down press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false); + case 2: + babyArrow.animation.addByPrefix('static', 'arrowUP'); + babyArrow.animation.addByPrefix('pressed', 'up press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false); + case 3: + babyArrow.animation.addByPrefix('static', 'arrowRIGHT'); + babyArrow.animation.addByPrefix('pressed', 'right press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false); + } + } + + // babyArrow.x += Note.swagWidth * 1; + babyArrow.x = (FlxG.width * 0.25) + (Note.swagWidth * (i - 2)); + babyArrow.updateHitbox(); + babyArrow.scrollFactor.set(); + + if (!isStoryMode) + { + babyArrow.y -= 10; + babyArrow.alpha = 0; + FlxTween.tween(babyArrow, {y: babyArrow.y + 10, alpha: 1}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * i)}); + } + + babyArrow.ID = i; + + if (player == 1) + { + playerStrums.add(babyArrow); + } else { + babyArrow.cpu = true; + cpuStrums.add(babyArrow); + } + + babyArrow.animation.play('static'); + babyArrow.x += ((FlxG.width / 2) * player); + + strumLineNotes.add(babyArrow); + } + } + + function tweenCamIn():Void + { + FlxTween.tween(FlxG.camera, {zoom: 1.3}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut}); + } + + override function openSubState(SubState:FlxSubState) + { + if (paused) + { + if (FlxG.sound.music != null) + { + FlxG.sound.music.pause(); + vocals.pause(); + } + + if (!startTimer.finished) + startTimer.active = false; + } + + super.openSubState(SubState); + } + + override function closeSubState() + { + if (paused) + { + if (FlxG.sound.music != null && !startingSong) + { + resyncVocals(); + } + + if (!startTimer.finished) + startTimer.active = true; + paused = false; + + #if desktop + if (startTimer.finished) + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength - Conductor.songPosition); + } + else + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + } + #end + } + + super.closeSubState(); + } + + override public function onFocus():Void + { + #if desktop + if (health > 0 && !paused) + { + if (Conductor.songPosition > 0.0) + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength - Conductor.songPosition); + } + else + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + } + } + #end + + super.onFocus(); + } + + override public function onFocusLost():Void + { + #if desktop + if (health > 0 && !paused) + { + DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + } + #end + + super.onFocusLost(); + } + + function resyncVocals():Void + { + vocals.pause(); + + FlxG.sound.music.play(); + Conductor.songPosition = FlxG.sound.music.time; + vocals.time = Conductor.songPosition; + vocals.play(); + } + + private var paused:Bool = false; + var startedCountdown:Bool = false; + var canPause:Bool = true; + + + public function pauseGame() { + persistentUpdate = false; + persistentDraw = true; + paused = true; + + // 1 / 1000 chance for Gitaroo Man easter egg + if (FlxG.random.bool(0.1)) + { + // gitaroo man easter egg + FlxG.switchState(new GitarooPause()); + } + else + openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); + + updateDiscordStatus(); + } + + // TODO: Update Discord Status + public function updateDiscordStatus() { + #if desktop + // Song duration in a float, useful for the time left feature + songLength = FlxG.sound.music.length; + + // Updating Discord Rich Presence (with Time Left) + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength); + #end + } + override public function update(elapsed:Float) + { + #if !debug + perfectMode = false; + #end + + super.update(elapsed); + + scoreTxt.text = "Score:" + songScore; + + if (FlxG.keys.justPressed.ENTER && startedCountdown && canPause) + pauseGame(); + + if (FlxG.keys.justPressed.SEVEN) + { + FlxG.switchState(new ChartingState()); + + #if desktop + DiscordClient.changePresence("Chart Editor", null, null, true); + #end + } + + // FlxG.watch.addQuick('VOL', vocals.amplitudeLeft); + // FlxG.watch.addQuick('VOLRight', vocals.amplitudeRight); + + iconP1.setGraphicSize(Std.int(FlxMath.lerp(150, iconP1.width, 0.50))); + iconP2.setGraphicSize(Std.int(FlxMath.lerp(150, iconP2.width, 0.50))); + + iconP1.updateHitbox(); + iconP2.updateHitbox(); + + var iconOffset:Int = 26; + + iconP1.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01) - iconOffset); + iconP2.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01)) - (iconP2.width - iconOffset); + + if (health > 2) + health = 2; + + if (healthBar.percent < 20) + iconP1.animation.curAnim.curFrame = 1; + else + iconP1.animation.curAnim.curFrame = 0; + + if (healthBar.percent > 80) + iconP2.animation.curAnim.curFrame = 1; + else + iconP2.animation.curAnim.curFrame = 0; + + /* if (FlxG.keys.justPressed.NINE) + FlxG.switchState(new Charting()); */ + + #if debug + if (FlxG.keys.justPressed.EIGHT) + FlxG.switchState(new AnimationDebug(SONG.player2)); + #end + + if (startingSong) + { + if (startedCountdown) + { + Conductor.songPosition += FlxG.elapsed * 1000; + if (Conductor.songPosition >= 0) + startSong(); + } + } + else + { + // Conductor.songPosition = FlxG.sound.music.time; + Conductor.songPosition += FlxG.elapsed * 1000; + + if (!paused) + { + songTime += FlxG.game.ticks - previousFrameTime; + previousFrameTime = FlxG.game.ticks; + + // Interpolation type beat + if (Conductor.lastSongPos != Conductor.songPosition) + { + songTime = (songTime + Conductor.songPosition) / 2; + Conductor.lastSongPos = Conductor.songPosition; + // Conductor.songPosition += FlxG.elapsed * 1000; + // trace('MISSED FRAME'); + } + } + + // Conductor.lastSongPos = FlxG.sound.music.time; + } + + if (generatedMusic && PlayState.SONG.notes[Std.int(curStep / 16)] != null) + { + if (curBeat % 4 == 0) + { + // trace(PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection); + } + + if (camFollow.x != dad.getMidpoint().x + 150 && !PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection) + { + camFollow.setPosition(dad.getMidpoint().x + 150, dad.getMidpoint().y - 100); + // camFollow.setPosition(lucky.getMidpoint().x - 120, lucky.getMidpoint().y + 210); + + switch (dad.curCharacter) + { + case 'mom': + camFollow.y = dad.getMidpoint().y; + case 'senpai': + camFollow.y = dad.getMidpoint().y - 430; + camFollow.x = dad.getMidpoint().x - 100; + case 'senpai-angry': + camFollow.y = dad.getMidpoint().y - 430; + camFollow.x = dad.getMidpoint().x - 100; + } + + if (dad.curCharacter == 'mom') + vocals.volume = 1; + + if (SONG.song.toLowerCase() == 'tutorial') + { + tweenCamIn(); + } + } + + if (PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection && camFollow.x != boyfriend.getMidpoint().x - 100) + { + camFollow.setPosition(boyfriend.getMidpoint().x - 100, boyfriend.getMidpoint().y - 100); + + switch (curStage) + { + case 'limo': + camFollow.x = boyfriend.getMidpoint().x - 300; + case 'mall': + camFollow.y = boyfriend.getMidpoint().y - 200; + case 'school': + camFollow.x = boyfriend.getMidpoint().x - 200; + camFollow.y = boyfriend.getMidpoint().y - 200; + case 'schoolEvil': + camFollow.x = boyfriend.getMidpoint().x - 200; + camFollow.y = boyfriend.getMidpoint().y - 200; + } + + if (SONG.song.toLowerCase() == 'tutorial') + { + FlxTween.tween(FlxG.camera, {zoom: 1}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut}); + } + } + } + + if (camZooming) + { + FlxG.camera.zoom = FlxMath.lerp(defaultCamZoom, FlxG.camera.zoom, 0.95); + camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, 0.95); + } + + FlxG.watch.addQuick("beatShit", curBeat); + FlxG.watch.addQuick("stepShit", curStep); + + if (curSong == 'Fresh') + { + switch (curBeat) + { + case 16: + camZooming = true; + gfSpeed = 2; + case 48: + gfSpeed = 1; + case 80: + gfSpeed = 2; + case 112: + gfSpeed = 1; + case 163: + // FlxG.sound.music.stop(); + // FlxG.switchState(new TitleState()); + } + } + + if (curSong == 'Bopeebo') + { + switch (curBeat) + { + case 128, 129, 130: + vocals.volume = 0; + // FlxG.sound.music.stop(); + // FlxG.switchState(new PlayState()); + } + } + // better streaming of shit + + // RESET = Quick Game Over Screen + if (controls.RESET) + { + health = 0; + trace("RESET = True"); + } + + // CHEAT = brandon's a pussy + if (controls.CHEAT) + { + health += 1; + trace("User is cheating!"); + } + + if (health <= 0) + { + boyfriend.stunned = true; + + persistentUpdate = false; + persistentDraw = false; + paused = true; + + vocals.stop(); + FlxG.sound.music.stop(); + + openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); + + // FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); + + #if desktop + // Game Over doesn't get his own variable because it's only used here + DiscordClient.changePresence("Game Over - " + detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + #end + } + + var addedNote:Bool = false; + while(unspawnNotes[0] != null && unspawnNotes[0].strumTime - Conductor.songPosition < 1500) { + addedNote = true; + notes.add(unspawnNotes.shift()); + } + if (addedNote) notes.sort(function(i, p1, p2) {return sortByShit(p1, p2);}); + + if (generatedMusic) + { + notes.forEachAlive(function(daNote:Note) + { + if (!daNote.mustPress && !daNote.wasGoodHit && daNote.strumTime <= Conductor.songPosition) goodNoteHit(daNote); + var strum:Strum = null; + for(e in (daNote.mustPress ? playerStrums : cpuStrums).members) { + if (e.ID == daNote.noteData % 4) { + strum = e; + break; + } + } + if (strum == null) return; + + strum.updateNotePosition(daNote); + }); + } + + if (!inCutscene) + keyShit(); + + #if debug + if (FlxG.keys.justPressed.ONE) + endSong(); + #end + } + + function endSong():Void + { + canPause = false; + FlxG.sound.music.volume = 0; + vocals.volume = 0; + if (SONG.validScore) + { + #if !switch + Highscore.saveScore(SONG.song, songScore, storyDifficulty); + #end + } + + if (isStoryMode) + { + campaignScore += songScore; + + storyPlaylist.remove(storyPlaylist[0]); + + if (storyPlaylist.length <= 0) + { + FlxG.sound.playMusic(Paths.music('freakyMenu')); + + transIn = FlxTransitionableState.defaultTransIn; + transOut = FlxTransitionableState.defaultTransOut; + + FlxG.switchState(new StoryMenuState()); + + // if () + StoryMenuState.weekUnlocked[Std.int(Math.min(storyWeek + 1, StoryMenuState.weekUnlocked.length - 1))] = true; + + if (SONG.validScore) + { + Highscore.saveWeekScore(storyWeek, campaignScore, storyDifficulty); + } + + FlxG.save.data.weekUnlocked = StoryMenuState.weekUnlocked; + FlxG.save.flush(); + } + else + { + var difficulty:String = ""; + + if (storyDifficulty == 0) + difficulty = '-easy'; + + if (storyDifficulty == 2) + difficulty = '-hard'; + + trace('LOADING NEXT SONG'); + trace(PlayState.storyPlaylist[0].toLowerCase() + difficulty); + + if (SONG.song.toLowerCase() == 'eggnog') + { + var blackShit:FlxSprite = new FlxSprite(-FlxG.width * FlxG.camera.zoom, + -FlxG.height * FlxG.camera.zoom).makeGraphic(FlxG.width * 3, FlxG.height * 3, FlxColor.BLACK); + blackShit.scrollFactor.set(); + add(blackShit); + camHUD.visible = false; + + FlxG.sound.play(Paths.sound('Lights_Shut_off')); + } + + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; + prevCamFollow = camFollow; + + PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + difficulty, PlayState.storyPlaylist[0]); + FlxG.sound.music.stop(); + + LoadingState.loadAndSwitchState(new PlayState()); + } + } + else + { + trace('WENT BACK TO FREEPLAY??'); + FlxG.switchState(new FreeplayState()); + } + } + + var endingSong:Bool = false; + + private function popUpScore(strumtime:Float):Void + { + var noteDiff:Float = Math.abs(strumtime - Conductor.songPosition); + // boyfriend.playAnim('hey'); + vocals.volume = 1; + + var placement:String = Std.string(combo); + + var coolText:FlxText = new FlxText(0, 0, 0, placement, 32); + coolText.screenCenter(); + coolText.x = FlxG.width * 0.55; + // + + var rating:FlxSprite = new FlxSprite(); + var score:Int = 350; + + var daRating:String = "sick"; + + if (noteDiff > Conductor.safeZoneOffset * 0.9) + { + daRating = 'shit'; + score = 50; + } + else if (noteDiff > Conductor.safeZoneOffset * 0.75) + { + daRating = 'bad'; + score = 100; + } + else if (noteDiff > Conductor.safeZoneOffset * 0.2) + { + daRating = 'good'; + score = 200; + } + + songScore += score; + + /* if (combo > 60) + daRating = 'sick'; + else if (combo > 12) + daRating = 'good' + else if (combo > 4) + daRating = 'bad'; + */ + + var pixelShitPart1:String = ""; + var pixelShitPart2:String = ''; + + if (curStage.startsWith('school')) + { + pixelShitPart1 = 'weeb/pixelUI/'; + pixelShitPart2 = '-pixel'; + } + + rating.loadGraphic(Paths.image(pixelShitPart1 + daRating + pixelShitPart2)); + rating.screenCenter(); + rating.x = coolText.x - 40; + rating.y -= 60; + rating.acceleration.y = 550; + rating.velocity.y -= FlxG.random.int(140, 175); + rating.velocity.x -= FlxG.random.int(0, 10); + + var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); + comboSpr.screenCenter(); + comboSpr.x = coolText.x; + comboSpr.acceleration.y = 600; + comboSpr.velocity.y -= 150; + + comboSpr.velocity.x += FlxG.random.int(1, 10); + add(rating); + + if (!curStage.startsWith('school')) + { + rating.setGraphicSize(Std.int(rating.width * 0.7)); + rating.antialiasing = true; + comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7)); + comboSpr.antialiasing = true; + } + else + { + rating.setGraphicSize(Std.int(rating.width * daPixelZoom * 0.7)); + comboSpr.setGraphicSize(Std.int(comboSpr.width * daPixelZoom * 0.7)); + } + + comboSpr.updateHitbox(); + rating.updateHitbox(); + + var seperatedScore:Array = []; + + seperatedScore.push(Math.floor(combo / 100)); + seperatedScore.push(Math.floor((combo - (seperatedScore[0] * 100)) / 10)); + seperatedScore.push(combo % 10); + + var daLoop:Int = 0; + for (i in seperatedScore) + { + var numScore:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2)); + numScore.screenCenter(); + numScore.x = coolText.x + (43 * daLoop) - 90; + numScore.y += 80; + + if (!curStage.startsWith('school')) + { + numScore.antialiasing = true; + numScore.setGraphicSize(Std.int(numScore.width * 0.5)); + } + else + { + numScore.setGraphicSize(Std.int(numScore.width * daPixelZoom)); + } + numScore.updateHitbox(); + + numScore.acceleration.y = FlxG.random.int(200, 300); + numScore.velocity.y -= FlxG.random.int(140, 160); + numScore.velocity.x = FlxG.random.float(-5, 5); + + if (combo >= 10 || combo == 0) + add(numScore); + + FlxTween.tween(numScore, {alpha: 0}, 0.2, { + onComplete: function(tween:FlxTween) + { + numScore.destroy(); + }, + startDelay: Conductor.crochet * 0.002 + }); + + daLoop++; + } + /* + trace(combo); + trace(seperatedScore); + */ + + coolText.text = Std.string(seperatedScore); + // add(coolText); + + FlxTween.tween(rating, {alpha: 0}, 0.2, { + startDelay: Conductor.crochet * 0.001 + }); + + FlxTween.tween(comboSpr, {alpha: 0}, 0.2, { + onComplete: function(tween:FlxTween) + { + coolText.destroy(); + comboSpr.destroy(); + + rating.destroy(); + }, + startDelay: Conductor.crochet * 0.001 + }); + + curSection += 1; + } + + private function keyShit():Void + { + // HOLDING + var pressed = [controls.LEFT, controls.DOWN, controls.UP, controls.RIGHT]; + var justPressed = [controls.LEFT_P, controls.DOWN_P, controls.UP_P, controls.RIGHT_P]; + var justReleased = [controls.LEFT_R, controls.DOWN_R, controls.UP_R, controls.RIGHT_R]; + + var funcsToExec:ArrayVoid> = []; + if (pressed.contains(true)) { + funcsToExec.push(function(note:Note) { + if (pressed[note.strumID] && note.isSustainNote && note.mustPress && !note.wasGoodHit) { + goodNoteHit(note); + } + }); + } + + var notePerStrum = [for(i in 0...4) null]; + var additionalNotes:Array = []; + if (justPressed.contains(true)) { + funcsToExec.push(function(note:Note) { + if (justPressed[note.strumID] && !note.isSustainNote && note.mustPress && !note.wasGoodHit && note.canBeHit) { + if (notePerStrum[note.strumID] == null) notePerStrum[note.strumID] = note; + else if (Math.abs(notePerStrum[note.strumID].strumTime - note.strumTime) <= 10) additionalNotes.push(note); + else if (note.strumTime < notePerStrum[note.strumID].strumTime) notePerStrum[note.strumID] = note; + } + }); + } + + notes.forEachAlive(function(note:Note) { + for(e in funcsToExec) e(note); + }); + + for(e in notePerStrum) if (e != null) goodNoteHit(e); + for(e in additionalNotes) goodNoteHit(e); + + playerStrums.forEach(function(str:Strum) { + str.updatePlayerInput(pressed[str.ID], justPressed[str.ID], justReleased[str.ID]); + }); + } + + function noteMiss(direction:Int = 1):Void + { + if (!boyfriend.stunned) + { + health -= 0.04; + if (combo > 5 && gf.animOffsets.exists('sad')) + { + gf.playAnim('sad'); + } + combo = 0; + + songScore -= 10; + + FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); + // FlxG.sound.play(Paths.sound('missnote1'), 1, false); + // FlxG.log.add('played imss note'); + + boyfriend.stunned = true; + + // get stunned for 5 seconds + new FlxTimer().start(5 / 60, function(tmr:FlxTimer) + { + boyfriend.stunned = false; + }); + + switch (direction) + { + case 0: + boyfriend.playAnim('singLEFTmiss', true); + case 1: + boyfriend.playAnim('singDOWNmiss', true); + case 2: + boyfriend.playAnim('singUPmiss', true); + case 3: + boyfriend.playAnim('singRIGHTmiss', true); + } + } + } + + function badNoteCheck() + { + // just double pasting this shit cuz fuk u + // REDO THIS SYSTEM! + var upP = controls.UP_P; + var rightP = controls.RIGHT_P; + var downP = controls.DOWN_P; + var leftP = controls.LEFT_P; + + if (leftP) + noteMiss(0); + if (downP) + noteMiss(1); + if (upP) + noteMiss(2); + if (rightP) + noteMiss(3); + } + + function noteCheck(keyP:Bool, note:Note):Void + { + if (keyP) + goodNoteHit(note); + else + { + badNoteCheck(); + } + } + + function goodNoteHit(note:Note):Void + { + if (!note.wasGoodHit) + { + if (note.mustPress) { + if (!note.isSustainNote) + { + popUpScore(note.strumTime); + combo++; + } + + if (note.noteData >= 0) + health += 0.023; + else + health += 0.004; + + // TODO: NOTE PRESSED HANDLER + switch (note.noteData) + { + case 0: + boyfriend.playAnim('singLEFT', true); + case 1: + boyfriend.playAnim('singDOWN', true); + case 2: + boyfriend.playAnim('singUP', true); + case 3: + boyfriend.playAnim('singRIGHT', true); + } + + playerStrums.forEach(function(str:Strum) { + if (str.ID == Math.abs(note.noteData % 4)) { + str.press(note.strumTime); + } + }); + } else { + // TODO: NOTE PRESSED HANDLER FOR DAD + switch (note.noteData) + { + case 0: + dad.playAnim('singLEFT', true); + case 1: + dad.playAnim('singDOWN', true); + case 2: + dad.playAnim('singUP', true); + case 3: + dad.playAnim('singRIGHT', true); + } + + cpuStrums.forEach(function(str:Strum) { + if (str.ID == Math.abs(note.noteData % 4)) { + str.press(note.strumTime); + } + }); + } + + note.wasGoodHit = true; + vocals.volume = 1; + + if (!note.isSustainNote) deleteNote(note); + } + } + + public function deleteNote(note:Note) { + note.kill(); + notes.remove(note, true); + note.destroy(); + } + + override function stepHit() + { + super.stepHit(); + if (FlxG.sound.music.time > Conductor.songPosition + 20 || FlxG.sound.music.time < Conductor.songPosition - 20) + { + resyncVocals(); + } + + if (dad.curCharacter == 'spooky' && curStep % 4 == 2) + { + // dad.dance(); + } + } + + var lightningStrikeBeat:Int = 0; + var lightningOffset:Int = 8; + + override function beatHit() + { + super.beatHit(); + + if (SONG.notes[Math.floor(curStep / 16)] != null) + { + if (SONG.notes[Math.floor(curStep / 16)].changeBPM) + { + Conductor.changeBPM(SONG.notes[Math.floor(curStep / 16)].bpm); + FlxG.log.add('CHANGED BPM!'); + } + // else + // Conductor.changeBPM(SONG.bpm); + + // Dad doesnt interupt his own notes + if (SONG.notes[Math.floor(curStep / 16)].mustHitSection) + dad.dance(); + } + // FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM); + + // HARDCODING FOR MILF ZOOMS! + if (curSong.toLowerCase() == 'milf' && curBeat >= 168 && curBeat < 200 && camZooming && FlxG.camera.zoom < 1.35) + { + FlxG.camera.zoom += 0.015; + camHUD.zoom += 0.03; + } + + if (camZooming && FlxG.camera.zoom < 1.35 && curBeat % 4 == 0) + { + FlxG.camera.zoom += 0.015; + camHUD.zoom += 0.03; + } + + iconP1.setGraphicSize(Std.int(iconP1.width + 30)); + iconP2.setGraphicSize(Std.int(iconP2.width + 30)); + + iconP1.updateHitbox(); + iconP2.updateHitbox(); + + if (curBeat % gfSpeed == 0) + { + gf.dance(); + } + } + + var curLight:Int = 0; +} diff --git a/source/funkin/game/Strum.hx b/source/funkin/game/Strum.hx new file mode 100644 index 00000000..b6e68fb8 --- /dev/null +++ b/source/funkin/game/Strum.hx @@ -0,0 +1,56 @@ +package funkin.game; + +import flixel.FlxSprite; +import flixel.math.FlxMath; + +class Strum extends FlxSprite { + public var cpu = false; + public var lastHit:Float = -5000; + + public override function update(elapsed:Float) { + super.update(elapsed); + if (cpu) { + if (lastHit + (Conductor.crochet) < Conductor.songPosition && getAnim() == "confirm") { + playAnim("static"); + } + } + } + + public function updateNotePosition(daNote:Note) { + daNote.y = (y - (Conductor.songPosition - daNote.strumTime) * (0.45 * FlxMath.roundDecimal(PlayState.SONG.speed, 2))); + daNote.x = x; + } + + public function updatePlayerInput(pressed:Bool, justPressed:Bool, justReleased:Bool) { + switch(getAnim()) { + case "confirm": + if (justReleased || !pressed) + playAnim("static"); + case "pressed": + if (justReleased || !pressed) + playAnim("static"); + case "static": + if (justPressed || pressed) + playAnim("pressed"); + case null: + playAnim("static"); + } + centerOffsets(); + centerOrigin(); + } + + public function press(time:Float) { + lastHit = time; + playAnim("confirm"); + centerOffsets(); + centerOrigin(); + } + + public function playAnim(anim:String, force:Bool = true) { + var oldAnim = animation.curAnim; + animation.play(anim, force); + } + public function getAnim() { + return animation.curAnim == null ? null : animation.curAnim.name; + } +} \ No newline at end of file diff --git a/source/funkin/macros/BuildCounterMacro.hx b/source/funkin/macros/BuildCounterMacro.hx new file mode 100644 index 00000000..f0bb1c2e --- /dev/null +++ b/source/funkin/macros/BuildCounterMacro.hx @@ -0,0 +1,22 @@ +package funkin.macros; + +import haxe.macro.Expr.Field; +import haxe.macro.Context; +import sys.io.File; + +class BuildCounterMacro { + public static function build():Array { + var buildNum:Int = Std.parseInt(File.getContent("buildnumber.txt")); + buildNum++; + + var fields = Context.getBuildFields(); + fields.push({ + name: "buildNumber", + access: [APublic, AStatic, AInline], + kind: FieldType.FVar(macro:Int, macro $v{buildNum}), + pos: Context.currentPos(), + }); + File.saveContent("buildnumber.txt", Std.string(buildNum)); + return fields; + } +} \ No newline at end of file diff --git a/source/import.hx b/source/import.hx index e0a4198e..c6c54328 100644 --- a/source/import.hx +++ b/source/import.hx @@ -1 +1,4 @@ -import Paths; \ No newline at end of file +#if !macro + import Paths; + import funkin.game.PlayState; +#end \ No newline at end of file