From b0f23985da4d4a38115c4b4ae476ce8959768c36 Mon Sep 17 00:00:00 2001 From: Prokube <68293280+prokube@users.noreply.github.com> Date: Mon, 3 May 2021 20:15:45 -0700 Subject: [PATCH 1/4] labels are pog --- source/PlayState.hx | 4261 ++++++++++++------------------------------- 1 file changed, 1136 insertions(+), 3125 deletions(-) diff --git a/source/PlayState.hx b/source/PlayState.hx index 6d7d5cf..104763f 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -1,3336 +1,1347 @@ package; -import haxe.Exception; -import openfl.geom.Matrix; -import openfl.display.BitmapData; -import openfl.utils.AssetType; -import lime.graphics.Image; -import flixel.graphics.FlxGraphic; -import openfl.utils.AssetManifest; -import openfl.utils.AssetLibrary; -import flixel.system.FlxAssets; - -import lime.app.Application; -import lime.media.AudioContext; -import lime.media.AudioManager; -import openfl.Lib; +import flixel.addons.ui.FlxUIText; +import haxe.zip.Writer; +import Conductor.BPMChangeEvent; 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.addons.ui.FlxInputText; +import flixel.addons.ui.FlxUI9SliceSprite; +import flixel.addons.ui.FlxUI; +import flixel.addons.ui.FlxUICheckBox; +import flixel.addons.ui.FlxUIDropDownMenu; +import flixel.addons.ui.FlxUIInputText; +import flixel.addons.ui.FlxUINumericStepper; +import flixel.addons.ui.FlxUITabMenu; +import flixel.addons.ui.FlxUITooltip.FlxUITooltipStyle; import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.group.FlxGroup; 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.ui.FlxButton; +import flixel.ui.FlxSpriteButton; 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; - -#if windows -import Discord.DiscordClient; -#end -#if windows -import Sys; -import sys.FileSystem; -#end +import openfl.events.Event; +import openfl.events.IOErrorEvent; +import openfl.events.IOErrorEvent; +import openfl.events.IOErrorEvent; +import openfl.media.Sound; +import openfl.net.FileReference; +import openfl.utils.ByteArray; using StringTools; -class PlayState extends MusicBeatState +class ChartingState extends MusicBeatState { - public static var instance:PlayState = null; + var _file:FileReference; - 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; - public static var weekSong:Int = 0; - public static var shits:Int = 0; - public static var bads:Int = 0; - public static var goods:Int = 0; - public static var sicks:Int = 0; + var UI_box:FlxUITabMenu; - public static var songPosBG:FlxSprite; - public static var songPosBar:FlxBar; + /** + * Array of notes showing when each section STARTS in STEPS + * Usually rounded up?? + */ + var curSection:Int = 0; - public static var rep:Replay; - public static var loadRep:Bool = false; + public static var lastSection:Int = 0; - public static var noteBools:Array = [false, false, false, false]; + var bpmTxt:FlxText; - var halloweenLevel:Bool = false; + var strumLine:FlxSprite; + var curSong:String = 'Dadbattle'; + var amountSteps:Int = 0; + var bullshitUI:FlxGroup; + var writingNotesText:FlxText; + var highlight:FlxSprite; - var songLength:Float = 0; - var kadeEngineWatermark:FlxText; - - #if windows - // Discord RPC variables - var storyDifficultyText:String = ""; - var iconRPC:String = ""; - var detailsText:String = ""; - var detailsPausedText:String = ""; - #end + var GRID_SIZE:Int = 40; - private var vocals:FlxSound; + var dummyArrow:FlxSprite; - public static var dad:Character; - public static var gf:Character; - public static var boyfriend:Boyfriend; + var curRenderedNotes:FlxTypedGroup; + var curRenderedSustains:FlxTypedGroup; - public var notes:FlxTypedGroup; - private var unspawnNotes:Array = []; + var gridBG:FlxSprite; - public var strumLine:FlxSprite; - private var curSection:Int = 0; + var _song:SwagSong; - private var camFollow:FlxObject; + var typingShit:FlxInputText; + /* + * WILL BE THE CURRENT / LAST PLACED NOTE + **/ + var curSelectedNote:Array; - private static var prevCamFollow:FlxObject; + var tempBpm:Int = 0; + var gridBlackLine:FlxSprite; + var vocals:FlxSound; - public static var strumLineNotes:FlxTypedGroup = null; - public static var playerStrums:FlxTypedGroup = null; + var player2:Character = new Character(0,0, "dad"); + var player1:Boyfriend = new Boyfriend(0,0, "bf"); - private var camZooming:Bool = false; - private var curSong:String = ""; + var leftIcon:HealthIcon; + var rightIcon:HealthIcon; - private var gfSpeed:Int = 1; - private var health:Float = 1; - private var combo:Int = 0; - public static var misses:Int = 0; - private var accuracy:Float = 0.00; - private var accuracyDefault:Float = 0.00; - private var totalNotesHit:Float = 0; - private var totalNotesHitDefault:Float = 0; - private var totalPlayed:Int = 0; - private var ss:Bool = false; + private var lastNote:Note; - - private var healthBarBG:FlxSprite; - private var healthBar:FlxBar; - private var songPositionBar:Float = 0; - - private var generatedMusic:Bool = false; - private var startingSong:Bool = false; - - private var iconP1:HealthIcon; - private var iconP2:HealthIcon; - public var camHUD:FlxCamera; - private var camGame:FlxCamera; - - public static var offsetTesting:Bool = false; - - var notesHitArray:Array = []; - var currentFrames:Int = 0; - - var dialogue:Array = ['dad:blah blah blah', 'bf: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 songName:FlxText; - var upperBoppers:FlxSprite; - var bottomBoppers:FlxSprite; - var santa:FlxSprite; - - var fc:Bool = true; - - var bgGirls:BackgroundGirls; - var wiggleShit:WiggleEffect = new WiggleEffect(); - - var talking:Bool = true; - var songScore:Int = 0; - var songScoreDef:Int = 0; - var scoreTxt:FlxText; - var replayTxt:FlxText; - - public static var campaignScore:Int = 0; - - var defaultCamZoom:Float = 1.05; - - public static var daPixelZoom:Float = 6; - - public static var theFunne:Bool = true; - var funneEffect:FlxSprite; - var inCutscene:Bool = false; - public static var repPresses:Int = 0; - public static var repReleases:Int = 0; - - public static var timeCurrently:Float = 0; - public static var timeCurrentlyR:Float = 0; - - // Will fire once to prevent debug spam messages and broken animations - private var triggeredAlready:Bool = false; - - // Will decide if she's even allowed to headbang at all depending on the song - private var allowedToHeadbang:Bool = false; - // Per song additive offset - public static var songOffset:Float = 0; - - private var executeModchart = false; - - // API stuff - - public function addObject(object:FlxBasic) { add(object); } - public function removeObject(object:FlxBasic) { remove(object); } - - - override public function create() + override function create() { - instance = this; - + curSection = lastSection; - if (FlxG.sound.music != null) - FlxG.sound.music.stop(); - - sicks = 0; - bads = 0; - shits = 0; - goods = 0; - - misses = 0; - - repPresses = 0; - repReleases = 0; - - #if windows - executeModchart = FileSystem.exists(Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart")); - #end - #if !cpp - executeModchart = false; // FORCE disable for non cpp targets - #end - - trace('Mod chart: ' + executeModchart + " - " + Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart")); - - #if windows - // 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; - } + if (PlayState.SONG != null) + _song = PlayState.SONG; else { - detailsText = "Freeplay"; + _song = { + song: 'Test', + notes: [], + bpm: 150, + needsVoices: true, + player1: 'bf', + player2: 'dad', + gfVersion: 'gf', + noteStyle: 'normal', + stage: 'stage', + speed: 1, + validScore: false + }; } - // String for when the game is paused - detailsPausedText = "Paused - " + detailsText; + gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * 16); + add(gridBG); - // Updating Discord Rich Presence. - DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); - #end + gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK); + add(gridBlackLine); + curRenderedNotes = new FlxTypedGroup(); + curRenderedSustains = new FlxTypedGroup(); - // var gameCam:FlxCamera = FlxG.camera; - camGame = new FlxCamera(); - camHUD = new FlxCamera(); - camHUD.bgColor.alpha = 0; + FlxG.mouse.visible = true; + FlxG.save.bind('funkin', 'ninjamuffin99'); - FlxG.cameras.reset(camGame); - FlxG.cameras.add(camHUD); + tempBpm = _song.bpm; - FlxCamera.defaultCameras = [camGame]; + addSection(); - persistentUpdate = true; - persistentDraw = true; + // sections = _song.notes; - if (SONG == null) - SONG = Song.loadFromJson('tutorial'); + updateGrid(); - Conductor.mapBPMChanges(SONG); - Conductor.changeBPM(SONG.bpm); + loadSong(_song.song); + Conductor.changeBPM(_song.bpm); + Conductor.mapBPMChanges(_song); - trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + Conductor.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: ' + Conductor.timeScale); - - 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')); - } + leftIcon = new HealthIcon(_song.player1); + rightIcon = new HealthIcon(_song.player2); + leftIcon.scrollFactor.set(1, 1); + rightIcon.scrollFactor.set(1, 1); - switch(SONG.stage) - { - case 'halloween': - { - curStage = 'spooky'; - halloweenLevel = true; + leftIcon.setGraphicSize(0, 45); + rightIcon.setGraphicSize(0, 45); - var hallowTex = Paths.getSparrowAtlas('halloween_bg','week2'); + add(leftIcon); + add(rightIcon); - 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); + leftIcon.setPosition(0, -100); + rightIcon.setPosition(gridBG.width / 2, -100); - isHalloween = true; - } - case 'philly': - { - curStage = 'philly'; + bpmTxt = new FlxText(1000, 50, 0, "", 16); + bpmTxt.scrollFactor.set(); + add(bpmTxt); - var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky', 'week3')); - bg.scrollFactor.set(0.1, 0.1); - add(bg); + strumLine = new FlxSprite(0, 50).makeGraphic(Std.int(FlxG.width / 2), 4); + add(strumLine); - var city:FlxSprite = new FlxSprite(-10).loadGraphic(Paths.image('philly/city', 'week3')); - city.scrollFactor.set(0.3, 0.3); - city.setGraphicSize(Std.int(city.width * 0.85)); - city.updateHitbox(); - add(city); + dummyArrow = new FlxSprite().makeGraphic(GRID_SIZE, GRID_SIZE); + add(dummyArrow); - phillyCityLights = new FlxTypedGroup(); - if(FlxG.save.data.distractions){ - add(phillyCityLights); - } + var tabs = [ + {name: "Song", label: 'Song'}, + {name: "Section", label: 'Section'}, + {name: "Note", label: 'Note Data'}, + {name: "Assets", label: 'Assets'} + ]; - for (i in 0...5) - { - var light:FlxSprite = new FlxSprite(city.x).loadGraphic(Paths.image('philly/win' + i, 'week3')); - 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); - } + UI_box = new FlxUITabMenu(null, tabs, true); - var streetBehind:FlxSprite = new FlxSprite(-40, 50).loadGraphic(Paths.image('philly/behindTrain','week3')); - add(streetBehind); + UI_box.resize(300, 400); + UI_box.x = FlxG.width / 2; + UI_box.y = 20; + add(UI_box); - phillyTrain = new FlxSprite(2000, 360).loadGraphic(Paths.image('philly/train','week3')); - if(FlxG.save.data.distractions){ - add(phillyTrain); - } + addSongUI(); + addSectionUI(); + addNoteUI(); - trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes','week3')); - 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','week3')); - add(street); - } - case 'limo': - { - curStage = 'limo'; - defaultCamZoom = 0.90; - - var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic(Paths.image('limo/limoSunset','week4')); - skyBG.scrollFactor.set(0.1, 0.1); - add(skyBG); - - var bgLimo:FlxSprite = new FlxSprite(-200, 480); - bgLimo.frames = Paths.getSparrowAtlas('limo/bgLimo','week4'); - bgLimo.animation.addByPrefix('drive', "background limo pink", 24); - bgLimo.animation.play('drive'); - bgLimo.scrollFactor.set(0.4, 0.4); - add(bgLimo); - if(FlxG.save.data.distractions){ - 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','week4')); - 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','week4'); - - 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','week4')); - // add(limo); - } - case 'mall': - { - curStage = 'mall'; - - defaultCamZoom = 0.80; - - var bg:FlxSprite = new FlxSprite(-1000, -500).loadGraphic(Paths.image('christmas/bgWalls','week5')); - 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','week5'); - 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(); - if(FlxG.save.data.distractions){ - add(upperBoppers); - } - - - var bgEscalator:FlxSprite = new FlxSprite(-1100, -600).loadGraphic(Paths.image('christmas/bgEscalator','week5')); - 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','week5')); - tree.antialiasing = true; - tree.scrollFactor.set(0.40, 0.40); - add(tree); - - bottomBoppers = new FlxSprite(-300, 140); - bottomBoppers.frames = Paths.getSparrowAtlas('christmas/bottomBop','week5'); - 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(); - if(FlxG.save.data.distractions){ - add(bottomBoppers); - } - - - var fgSnow:FlxSprite = new FlxSprite(-600, 700).loadGraphic(Paths.image('christmas/fgSnow','week5')); - fgSnow.active = false; - fgSnow.antialiasing = true; - add(fgSnow); - - santa = new FlxSprite(-840, 150); - santa.frames = Paths.getSparrowAtlas('christmas/santa','week5'); - santa.animation.addByPrefix('idle', 'santa idle in fear', 24, false); - santa.antialiasing = true; - if(FlxG.save.data.distractions){ - add(santa); - } - } - case 'mallEvil': - { - curStage = 'mallEvil'; - var bg:FlxSprite = new FlxSprite(-400, -500).loadGraphic(Paths.image('christmas/evilBG','week5')); - 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','week5')); - evilTree.antialiasing = true; - evilTree.scrollFactor.set(0.2, 0.2); - add(evilTree); - - var evilSnow:FlxSprite = new FlxSprite(-200, 700).loadGraphic(Paths.image("christmas/evilSnow",'week5')); - evilSnow.antialiasing = true; - add(evilSnow); - } - case 'school': - { - curStage = 'school'; - - // defaultCamZoom = 0.9; - - var bgSky = new FlxSprite().loadGraphic(Paths.image('weeb/weebSky','week6')); - bgSky.scrollFactor.set(0.1, 0.1); - add(bgSky); - - var repositionShit = -200; - - var bgSchool:FlxSprite = new FlxSprite(repositionShit, 0).loadGraphic(Paths.image('weeb/weebSchool','week6')); - bgSchool.scrollFactor.set(0.6, 0.90); - add(bgSchool); - - var bgStreet:FlxSprite = new FlxSprite(repositionShit).loadGraphic(Paths.image('weeb/weebStreet','week6')); - bgStreet.scrollFactor.set(0.95, 0.95); - add(bgStreet); - - var fgTrees:FlxSprite = new FlxSprite(repositionShit + 170, 130).loadGraphic(Paths.image('weeb/weebTreesBack','week6')); - fgTrees.scrollFactor.set(0.9, 0.9); - add(fgTrees); - - var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800); - var treetex = Paths.getPackerAtlas('weeb/weebTrees','week6'); - 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','week6'); - 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') - { - if(FlxG.save.data.distractions){ - bgGirls.getScared(); - } - } - - bgGirls.setGraphicSize(Std.int(bgGirls.width * daPixelZoom)); - bgGirls.updateHitbox(); - if(FlxG.save.data.distractions){ - add(bgGirls); - } - } - case 'schoolEvil': - { - 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','week6'); - 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); - */ - } - case 'stage': - { - 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); - } - 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 (SONG.gfVersion) - { - case 'gf-car': - gfVersion = 'gf-car'; - case 'gf-christmas': - gfVersion = 'gf-christmas'; - case 'gf-pixel': - gfVersion = 'gf-pixel'; - case 'gf': - gfVersion = 'gf'; - default: - gfVersion = 'gf'; - } - - 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; - if(FlxG.save.data.distractions){ - 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': - if(FlxG.save.data.distractions){ - // 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(); - - if (FlxG.save.data.downscroll) - strumLine.y = FlxG.height - 165; - - 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 * (30 / (cast (Lib.current.getChildAt(0), Main)).getFPS())); - // 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; - - if (FlxG.save.data.songPosition) // I dont wanna talk about this code :( - { - songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar')); - if (FlxG.save.data.downscroll) - songPosBG.y = FlxG.height * 0.9 + 45; - songPosBG.screenCenter(X); - songPosBG.scrollFactor.set(); - add(songPosBG); - - songPosBar = new FlxBar(songPosBG.x + 4, songPosBG.y + 4, LEFT_TO_RIGHT, Std.int(songPosBG.width - 8), Std.int(songPosBG.height - 8), this, - 'songPositionBar', 0, 90000); - songPosBar.scrollFactor.set(); - songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); - add(songPosBar); - - var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - 20,songPosBG.y,0,SONG.song, 16); - if (FlxG.save.data.downscroll) - songName.y -= 3; - songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - songName.scrollFactor.set(); - add(songName); - songName.cameras = [camHUD]; - } - - healthBarBG = new FlxSprite(0, FlxG.height * 0.9).loadGraphic(Paths.image('healthBar')); - if (FlxG.save.data.downscroll) - healthBarBG.y = 50; - 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); - - // Add Kade Engine watermark - kadeEngineWatermark = new FlxText(4,healthBarBG.y + 50,0,SONG.song + " " + (storyDifficulty == 2 ? "Hard" : storyDifficulty == 1 ? "Normal" : "Easy") + (Main.watermarks ? " - KE " + MainMenuState.kadeEngineVer : ""), 16); - kadeEngineWatermark.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - kadeEngineWatermark.scrollFactor.set(); - add(kadeEngineWatermark); - - if (FlxG.save.data.downscroll) - kadeEngineWatermark.y = FlxG.height * 0.9 + 45; - - scoreTxt = new FlxText(FlxG.width / 2 - 235, healthBarBG.y + 50, 0, "", 20); - if (!FlxG.save.data.accuracyDisplay) - scoreTxt.x = healthBarBG.x + healthBarBG.width / 2; - scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - scoreTxt.scrollFactor.set(); - if (offsetTesting) - scoreTxt.x += 300; - add(scoreTxt); - - replayTxt = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (FlxG.save.data.downscroll ? 100 : -100), 0, "REPLAY", 20); - replayTxt.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - replayTxt.scrollFactor.set(); - if (loadRep) - { - add(replayTxt); - } - - 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 (FlxG.save.data.songPosition) - { - songPosBG.cameras = [camHUD]; - songPosBar.cameras = [camHUD]; - } - kadeEngineWatermark.cameras = [camHUD]; - if (loadRep) - replayTxt.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(); - } - } - - if (!loadRep) - rep = new Replay("na"); + add(curRenderedNotes); + add(curRenderedSustains); super.create(); } - function schoolIntro(?dialogueBox:DialogueBox):Void + function addSongUI():Void { - var black:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); - black.scrollFactor.set(); - add(black); + var UI_songTitle = new FlxUIInputText(10, 10, 70, _song.song, 8); + typingShit = UI_songTitle; - 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') + var check_voices = new FlxUICheckBox(10, 25, null, null, "Has voice track", 100); + check_voices.checked = _song.needsVoices; + // _song.needsVoices = check_voices.checked; + check_voices.callback = function() { - remove(black); + _song.needsVoices = check_voices.checked; + trace('CHECKED!'); + }; - if (SONG.song.toLowerCase() == 'thorns') + var check_mute_inst = new FlxUICheckBox(10, 200, null, null, "Mute Instrumental (in editor)", 100); + check_mute_inst.checked = false; + check_mute_inst.callback = function() + { + var vol:Float = 1; + + if (check_mute_inst.checked) + vol = 0; + + FlxG.sound.music.volume = vol; + }; + + var saveButton:FlxButton = new FlxButton(110, 8, "Save", function() + { + saveLevel(); + }); + + var reloadSong:FlxButton = new FlxButton(saveButton.x + saveButton.width + 10, saveButton.y, "Reload Audio", function() + { + loadSong(_song.song); + }); + + var reloadSongJson:FlxButton = new FlxButton(reloadSong.x, saveButton.y + 30, "Reload JSON", function() + { + loadJson(_song.song.toLowerCase()); + }); + + + var restart = new FlxButton(10,140,"Reset Chart", function() + { + for (ii in 0..._song.notes.length) + { + for (i in 0..._song.notes[ii].sectionNotes.length) + { + _song.notes[ii].sectionNotes = []; + } + } + resetSection(true); + }); + + var loadAutosaveBtn:FlxButton = new FlxButton(reloadSongJson.x, reloadSongJson.y + 30, 'load autosave', loadAutosave); + + var stepperSpeed:FlxUINumericStepper = new FlxUINumericStepper(10, 80, 0.1, 1, 0.1, 10, 1); + stepperSpeed.value = _song.speed; + stepperSpeed.name = 'song_speed'; + + var stepperSpeedLabel = new FlxText(74,80,'Scroll Speed'); + + var stepperBPM:FlxUINumericStepper = new FlxUINumericStepper(10, 65, 0.1, 1, 1.0, 5000.0, 1); + stepperBPM.value = Conductor.bpm; + stepperBPM.name = 'song_bpm'; + + var stepperBPMLabel = new FlxText(74,65,'BPM'); + + var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); + var gfVersions:Array = CoolUtil.coolTextFile(Paths.txt('gfVersionList')); + var stages:Array = CoolUtil.coolTextFile(Paths.txt('stageList')); + var noteStyles:Array = CoolUtil.coolTextFile(Paths.txt('noteStyleList')); + + var player1DropDown = new FlxUIDropDownMenu(10, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) + { + _song.player1 = characters[Std.parseInt(character)]; + }); + player1DropDown.selectedLabel = _song.player1; + + var player1Label = new FlxText(10,80,64,'Player 1'); + + var player2DropDown = new FlxUIDropDownMenu(140, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) + { + _song.player2 = characters[Std.parseInt(character)]; + }); + player2DropDown.selectedLabel = _song.player2; + + var player2Label = new FlxText(140,80,64,'Player 2'); + + var gfVersionDropDown = new FlxUIDropDownMenu(10, 200, FlxUIDropDownMenu.makeStrIdLabelArray(gfVersions, true), function(gfVersion:String) { - add(red); + _song.gfVersion = gfVersions[Std.parseInt(gfVersion)]; + }); + gfVersionDropDown.selectedLabel = _song.gfVersion; + + var gfVersionLabel = new FlxText(10,180,64,'Girlfriend'); + + var stageDropDown = new FlxUIDropDownMenu(140, 200, FlxUIDropDownMenu.makeStrIdLabelArray(stages, true), function(stage:String) + { + _song.stage = stages[Std.parseInt(stage)]; + }); + stageDropDown.selectedLabel = _song.stage; + + var stageLabel = new FlxText(140,180,64,'Stage'); + + var noteStyleDropDown = new FlxUIDropDownMenu(10, 300, FlxUIDropDownMenu.makeStrIdLabelArray(noteStyles, true), function(noteStyle:String) + { + _song.noteStyle = noteStyles[Std.parseInt(noteStyle)]; + }); + noteStyleDropDown.selectedLabel = _song.noteStyle; + + var noteStyleLabel = new FlxText(10,280,64,'Note Skin'); + + var tab_group_song = new FlxUI(null, UI_box); + tab_group_song.name = "Song"; + tab_group_song.add(UI_songTitle); + tab_group_song.add(restart); + tab_group_song.add(check_voices); + tab_group_song.add(check_mute_inst); + tab_group_song.add(saveButton); + tab_group_song.add(reloadSong); + tab_group_song.add(reloadSongJson); + tab_group_song.add(loadAutosaveBtn); + tab_group_song.add(stepperBPM); + tab_group_song.add(stepperBPMLabel); + tab_group_song.add(stepperSpeed); + tab_group_song.add(stepperSpeedLabel); + + var tab_group_assets = new FlxUI(null, UI_box); + tab_group_assets.name = "Assets"; + tab_group_assets.add(noteStyleDropDown); + tab_group_assets.add(noteStyleLabel); + tab_group_assets.add(gfVersionDropDown); + tab_group_assets.add(gfVersionLabel); + tab_group_assets.add(stageDropDown); + tab_group_assets.add(stageLabel); + tab_group_assets.add(player1DropDown); + tab_group_assets.add(player2DropDown); + tab_group_assets.add(player1Label); + tab_group_assets.add(player2Label); + + UI_box.addGroup(tab_group_song); + UI_box.addGroup(tab_group_assets); + UI_box.scrollFactor.set(); + + FlxG.camera.follow(strumLine); + } + + var stepperLength:FlxUINumericStepper; + var check_mustHitSection:FlxUICheckBox; + var check_changeBPM:FlxUICheckBox; + var stepperSectionBPM:FlxUINumericStepper; + var check_altAnim:FlxUICheckBox; + + function addSectionUI():Void + { + var tab_group_section = new FlxUI(null, UI_box); + tab_group_section.name = 'Section'; + + stepperLength = new FlxUINumericStepper(10, 10, 4, 0, 0, 999, 0); + stepperLength.value = _song.notes[curSection].lengthInSteps; + stepperLength.name = "section_length"; + + stepperSectionBPM = new FlxUINumericStepper(10, 80, 1, Conductor.bpm, 0, 999, 0); + stepperSectionBPM.value = Conductor.bpm; + stepperSectionBPM.name = 'section_bpm'; + + var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 130, 1, 1, -999, 999, 0); + + var copyButton:FlxButton = new FlxButton(10, 130, "Copy last section", function() + { + copySection(Std.int(stepperCopy.value)); + }); + + var clearSectionButton:FlxButton = new FlxButton(10, 150, "Clear", clearSection); + + var swapSection:FlxButton = new FlxButton(10, 170, "Swap section", function() + { + for (i in 0..._song.notes[curSection].sectionNotes.length) + { + var note = _song.notes[curSection].sectionNotes[i]; + note[1] = (note[1] + 4) % 8; + _song.notes[curSection].sectionNotes[i] = note; + updateGrid(); + } + }); + + check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Must hit section", 100); + check_mustHitSection.name = 'check_mustHit'; + check_mustHitSection.checked = true; + // _song.needsVoices = check_mustHit.checked; + + check_altAnim = new FlxUICheckBox(10, 400, null, null, "Alt Animation", 100); + check_altAnim.name = 'check_altAnim'; + + check_changeBPM = new FlxUICheckBox(10, 60, null, null, 'Change BPM', 100); + check_changeBPM.name = 'check_changeBPM'; + + tab_group_section.add(stepperLength); + tab_group_section.add(stepperSectionBPM); + tab_group_section.add(stepperCopy); + tab_group_section.add(check_mustHitSection); + tab_group_section.add(check_altAnim); + tab_group_section.add(check_changeBPM); + tab_group_section.add(copyButton); + tab_group_section.add(clearSectionButton); + tab_group_section.add(swapSection); + + UI_box.addGroup(tab_group_section); + } + + var stepperSusLength:FlxUINumericStepper; + + var tab_group_note:FlxUI; + + function addNoteUI():Void + { + tab_group_note = new FlxUI(null, UI_box); + tab_group_note.name = 'Note'; + + writingNotesText = new FlxUIText(20,100, 0, ""); + writingNotesText.setFormat("Arial",20,FlxColor.WHITE,FlxTextAlign.LEFT,FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + + stepperSusLength = new FlxUINumericStepper(10, 10, Conductor.stepCrochet / 2, 0, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps * 4); + stepperSusLength.value = 0; + stepperSusLength.name = 'note_susLength'; + + var stepperSusLengthLabel = new FlxText(74,10,'Note Sustain Length'); + + var applyLength:FlxButton = new FlxButton(10, 100, 'Apply Data'); + + tab_group_note.add(writingNotesText); + tab_group_note.add(stepperSusLength); + tab_group_note.add(stepperSusLengthLabel); + tab_group_note.add(applyLength); + + UI_box.addGroup(tab_group_note); + + /*player2 = new Character(0,gridBG.y, _song.player2); + player1 = new Boyfriend(player2.width * 0.2,gridBG.y + player2.height, _song.player1); + + player1.y = player1.y - player1.height; + + player2.setGraphicSize(Std.int(player2.width * 0.2)); + player1.setGraphicSize(Std.int(player1.width * 0.2)); + + UI_box.add(player1); + UI_box.add(player2);*/ + + } + + function loadSong(daSong:String):Void + { + if (FlxG.sound.music != null) + { + FlxG.sound.music.stop(); + // vocals.stop(); + } + + FlxG.sound.playMusic(Paths.inst(daSong), 0.6); + + // WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER + vocals = new FlxSound().loadEmbedded(Paths.voices(daSong)); + FlxG.sound.list.add(vocals); + + FlxG.sound.music.pause(); + vocals.pause(); + + FlxG.sound.music.onComplete = function() + { + vocals.pause(); + vocals.time = 0; + FlxG.sound.music.pause(); + FlxG.sound.music.time = 0; + changeSection(); + }; + } + + function generateUI():Void + { + while (bullshitUI.members.length > 0) + { + bullshitUI.remove(bullshitUI.members[0], true); + } + + // general shit + var title:FlxText = new FlxText(UI_box.x + 20, UI_box.y + 20, 0); + bullshitUI.add(title); + /* + var loopCheck = new FlxUICheckBox(UI_box.x + 10, UI_box.y + 50, null, null, "Loops", 100, ['loop check']); + loopCheck.checked = curNoteSelected.doesLoop; + tooltips.add(loopCheck, {title: 'Section looping', body: "Whether or not it's a simon says style section", style: tooltipType}); + bullshitUI.add(loopCheck); + + */ + } + + override function getEvent(id:String, sender:Dynamic, data:Dynamic, ?params:Array) + { + if (id == FlxUICheckBox.CLICK_EVENT) + { + var check:FlxUICheckBox = cast sender; + var label = check.getLabel().text; + switch (label) + { + case 'Must hit section': + _song.notes[curSection].mustHitSection = check.checked; + case 'Change BPM': + _song.notes[curSection].changeBPM = check.checked; + FlxG.log.add('changed bpm shit'); + case "Alt Animation": + _song.notes[curSection].altAnim = check.checked; + } + } + else if (id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper)) + { + var nums:FlxUINumericStepper = cast sender; + var wname = nums.name; + FlxG.log.add(wname); + if (wname == 'section_length') + { + if (nums.value <= 4) + nums.value = 4; + _song.notes[curSection].lengthInSteps = Std.int(nums.value); + updateGrid(); + } + else if (wname == 'song_speed') + { + if (nums.value <= 0) + nums.value = 0; + _song.speed = nums.value; + } + else if (wname == 'song_bpm') + { + if (nums.value <= 0) + nums.value = 1; + tempBpm = Std.int(nums.value); + Conductor.mapBPMChanges(_song); + Conductor.changeBPM(Std.int(nums.value)); + } + else if (wname == 'note_susLength') + { + if (curSelectedNote == null) + return; + + if (nums.value <= 0) + nums.value = 0; + curSelectedNote[2] = nums.value; + updateGrid(); + } + else if (wname == 'section_bpm') + { + if (nums.value <= 0.1) + nums.value = 0.1; + _song.notes[curSection].bpm = Std.int(nums.value); + updateGrid(); } } - new FlxTimer().start(0.3, function(tmr:FlxTimer) + // FlxG.log.add(id + " WEED " + sender + " WEED " + data + " WEED " + params); + } + + var updatedSection:Bool = false; + + /* this function got owned LOL + function lengthBpmBullshit():Float { - black.alpha -= 0.15; - - if (black.alpha > 0) - { - tmr.reset(0.3); - } + if (_song.notes[curSection].changeBPM) + return _song.notes[curSection].lengthInSteps * (_song.notes[curSection].bpm / _song.bpm); else + return _song.notes[curSection].lengthInSteps; + }*/ + function sectionStartTime():Float + { + var daBPM:Int = _song.bpm; + var daPos:Float = 0; + for (i in 0...curSection) + { + if (_song.notes[i].changeBPM) { - if (dialogueBox != null) - { - inCutscene = true; + daBPM = _song.notes[i].bpm; + } + daPos += 4 * (1000 * 60 / daBPM); + } + return daPos; + } - if (SONG.song.toLowerCase() == 'thorns') - { - add(senpaiEvil); - senpaiEvil.alpha = 0; - new FlxTimer().start(0.3, function(swagTimer:FlxTimer) + var writingNotes:Bool = false; + + override function update(elapsed:Float) + { + updateHeads(); + + curStep = recalculateSteps(); + + if (FlxG.keys.justPressed.ALT && UI_box.selected_tab == 0) + { + writingNotes = !writingNotes; + } + + if (writingNotes) + writingNotesText.text = "WRITING NOTES"; + else + writingNotesText.text = ""; + + Conductor.songPosition = FlxG.sound.music.time; + _song.song = typingShit.text; + + var upP = controls.UP_P; + var rightP = controls.RIGHT_P; + var downP = controls.DOWN_P; + var leftP = controls.LEFT_P; + + var controlArray:Array = [leftP, downP, upP, rightP]; + + if ((upP || rightP || downP || leftP) && writingNotes) + { + for(i in 0...controlArray.length) + { + if (controlArray[i]) + { + for (n in 0..._song.notes[curSection].sectionNotes.length) { - senpaiEvil.alpha += 0.15; - if (senpaiEvil.alpha < 1) + var note = _song.notes[curSection].sectionNotes[n]; + if (note == null) + continue; + if (note[0] == Conductor.songPosition && note[1] % 4 == i) { - swagTimer.reset(); + trace('GAMING'); + _song.notes[curSection].sectionNotes.remove(note); } - else + } + trace('adding note'); + _song.notes[curSection].sectionNotes.push([Conductor.songPosition, i, 0]); + updateGrid(); + } + } + + } + + strumLine.y = getYfromStrum((Conductor.songPosition - sectionStartTime()) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps)); + + + /*curRenderedNotes.forEach(function(note:Note) { + if (strumLine.overlaps(note) && strumLine.y == note.y) // yandere dev type shit + { + if (_song.notes[curSection].mustHitSection) + { + trace('must hit ' + Math.abs(note.noteData)); + if (note.noteData < 4) + { + switch (Math.abs(note.noteData)) { - 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); - }); + case 2: + player1.playAnim('singUP', true); + case 3: + player1.playAnim('singRIGHT', true); + case 1: + player1.playAnim('singDOWN', true); + case 0: + player1.playAnim('singLEFT', true); } - }); + } + if (note.noteData >= 4) + { + switch (note.noteData) + { + case 6: + player2.playAnim('singUP', true); + case 7: + player2.playAnim('singRIGHT', true); + case 5: + player2.playAnim('singDOWN', true); + case 4: + player2.playAnim('singLEFT', true); + } + } } else { - add(dialogueBox); + trace('hit ' + Math.abs(note.noteData)); + if (note.noteData < 4) + { + switch (Math.abs(note.noteData)) + { + case 2: + player2.playAnim('singUP', true); + case 3: + player2.playAnim('singRIGHT', true); + case 1: + player2.playAnim('singDOWN', true); + case 0: + player2.playAnim('singLEFT', true); + } + } + if (note.noteData >= 4) + { + switch (note.noteData) + { + case 6: + player1.playAnim('singUP', true); + case 7: + player1.playAnim('singRIGHT', true); + case 5: + player1.playAnim('singDOWN', true); + case 4: + player1.playAnim('singLEFT', true); + } + } } - } - else - startCountdown(); - - remove(black); } - }); - } + });*/ - var startTimer:FlxTimer; - var perfectMode:Bool = false; - - var luaWiggles:Array = []; - - #if windows - public static var luaModchart:ModchartState = null; - #end - - function startCountdown():Void - { - inCutscene = false; - - generateStaticArrows(0); - generateStaticArrows(1); - - - #if windows - if (executeModchart) + if (curBeat % 4 == 0 && curStep >= 16 * (curSection + 1)) { - luaModchart = ModchartState.createModchartState(); - luaModchart.executeState('start',[PlayState.SONG.song]); - } - #end + trace(curStep); + trace((_song.notes[curSection].lengthInSteps) * (curSection + 1)); + trace('DUMBSHIT'); - 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 (_song.notes[curSection + 1] == null) { - if (value == curStage) + addSection(); + } + + changeSection(curSection + 1, false); + } + + FlxG.watch.addQuick('daBeat', curBeat); + FlxG.watch.addQuick('daStep', curStep); + + if (FlxG.mouse.justPressed) + { + if (FlxG.mouse.overlaps(curRenderedNotes)) + { + curRenderedNotes.forEach(function(note:Note) { - introAlts = introAssets.get(value); - altSuffix = '-pixel'; - } - } - - switch (swagCounter) - - { - case 0: - FlxG.sound.play(Paths.sound('intro3' + altSuffix), 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' + altSuffix), 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' + altSuffix), 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' + altSuffix), 0.6); - case 4: - } - - swagCounter += 1; - // generateSong('fresh'); - }, 5); - } - - var previousFrameTime:Int = 0; - var lastReportedPlayheadPosition:Int = 0; - var songTime:Float = 0; - - - var songStarted = false; - - function startSong():Void - { - startingSong = false; - songStarted = true; - 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(); - - // Song duration in a float, useful for the time left feature - songLength = FlxG.sound.music.length; - - if (FlxG.save.data.songPosition) - { - remove(songPosBG); - remove(songPosBar); - remove(songName); - - songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar')); - if (FlxG.save.data.downscroll) - songPosBG.y = FlxG.height * 0.9 + 45; - songPosBG.screenCenter(X); - songPosBG.scrollFactor.set(); - add(songPosBG); - - songPosBar = new FlxBar(songPosBG.x + 4, songPosBG.y + 4, LEFT_TO_RIGHT, Std.int(songPosBG.width - 8), Std.int(songPosBG.height - 8), this, - 'songPositionBar', 0, songLength - 1000); - songPosBar.numDivisions = 1000; - songPosBar.scrollFactor.set(); - songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); - add(songPosBar); - - var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - 20,songPosBG.y,0,SONG.song, 16); - if (FlxG.save.data.downscroll) - songName.y -= 3; - songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - songName.scrollFactor.set(); - add(songName); - - songPosBG.cameras = [camHUD]; - songPosBar.cameras = [camHUD]; - songName.cameras = [camHUD]; - } - - // Song check real quick - switch(curSong) - { - case 'Bopeebo' | 'Philly' | 'Blammed' | 'Cocoa' | 'Eggnog': allowedToHeadbang = true; - default: allowedToHeadbang = false; - } - - #if windows - // Updating Discord Rich Presence (with Time Left) - DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); - #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; - - // Per song offset check - #if windows - var songPath = 'assets/data/' + PlayState.SONG.song.toLowerCase() + '/'; - for(file in sys.FileSystem.readDirectory(songPath)) - { - var path = haxe.io.Path.join([songPath, file]); - if(!sys.FileSystem.isDirectory(path)) - { - if(path.endsWith('.offset')) + if (FlxG.mouse.overlaps(note)) { - trace('Found offset file: ' + path); - songOffset = Std.parseFloat(file.substring(0, file.indexOf('.off'))); - break; - }else { - trace('Offset file not found. Creating one @: ' + songPath); - sys.io.File.saveContent(songPath + songOffset + '.offset', ''); + if (FlxG.keys.pressed.CONTROL) + { + selectNote(note); + } + else + { + deleteNote(note); + } } + }); + } + else + { + if (FlxG.mouse.x > gridBG.x + && FlxG.mouse.x < gridBG.x + gridBG.width + && FlxG.mouse.y > gridBG.y + && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps)) + { + FlxG.log.add('added note'); + addNote(); } } - #end - var daBeats:Int = 0; // Not exactly representative of 'daBeats' lol, just how much it has looped - for (section in noteData) + } + + if (FlxG.mouse.x > gridBG.x + && FlxG.mouse.x < gridBG.x + gridBG.width + && FlxG.mouse.y > gridBG.y + && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps)) { - var coolSection:Int = Std.int(section.lengthInSteps / 4); + dummyArrow.x = Math.floor(FlxG.mouse.x / GRID_SIZE) * GRID_SIZE; + if (FlxG.keys.pressed.SHIFT) + dummyArrow.y = FlxG.mouse.y; + else + dummyArrow.y = Math.floor(FlxG.mouse.y / GRID_SIZE) * GRID_SIZE; + } - for (songNotes in section.sectionNotes) + if (FlxG.keys.justPressed.ENTER) + { + lastSection = curSection; + + PlayState.SONG = _song; + FlxG.sound.music.stop(); + vocals.stop(); + LoadingState.loadAndSwitchState(new PlayState()); + } + + if (FlxG.keys.justPressed.E) + { + changeNoteSustain(Conductor.stepCrochet); + } + if (FlxG.keys.justPressed.Q) + { + changeNoteSustain(-Conductor.stepCrochet); + } + + if (FlxG.keys.justPressed.TAB) + { + if (FlxG.keys.pressed.SHIFT) { - var daStrumTime:Float = songNotes[0] + FlxG.save.data.offset + songOffset; - if (daStrumTime < 0) - daStrumTime = 0; - var daNoteData:Int = Std.int(songNotes[1] % 4); + UI_box.selected_tab -= 1; + if (UI_box.selected_tab < 0) + UI_box.selected_tab = 2; + } + else + { + UI_box.selected_tab += 1; + if (UI_box.selected_tab >= 3) + UI_box.selected_tab = 0; + } + } - var gottaHitNote:Bool = section.mustHitSection; + if (!typingShit.hasFocus) + { - if (songNotes[1] > 3) + if (FlxG.keys.pressed.CONTROL) + { + if (FlxG.keys.justPressed.Z && lastNote != null) { - gottaHitNote = !section.mustHitSection; + trace(curRenderedNotes.members.contains(lastNote) ? "delete note" : "add note"); + if (curRenderedNotes.members.contains(lastNote)) + deleteNote(lastNote); + else + addNote(lastNote); } + } - 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)) + var shiftThing:Int = 1; + if (FlxG.keys.pressed.SHIFT) + shiftThing = 4; + if (!writingNotes) + { + if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.D) + changeSection(curSection + shiftThing); + if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.A) + changeSection(curSection - shiftThing); + } + if (FlxG.keys.justPressed.SPACE) + { + if (FlxG.sound.music.playing) { - 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 + FlxG.sound.music.pause(); + vocals.pause(); } else { + vocals.play(); + FlxG.sound.music.play(); } } - 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 (SONG.noteStyle) + if (FlxG.keys.justPressed.R) { - case 'pixel': - 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); - } - - case 'normal': - 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); - } - - 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); - } + if (FlxG.keys.pressed.SHIFT) + resetSection(true); + else + resetSection(); } - 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) + if (FlxG.mouse.wheel != 0) { FlxG.sound.music.pause(); vocals.pause(); + + FlxG.sound.music.time -= (FlxG.mouse.wheel * Conductor.stepCrochet * 0.4); + vocals.time = FlxG.sound.music.time; } - #if windows - DiscordClient.changePresence("PAUSED on " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "Acc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); - #end - if (!startTimer.finished) - startTimer.active = false; - } - - super.openSubState(SubState); - } - - override function closeSubState() - { - if (paused) - { - if (FlxG.sound.music != null && !startingSong) + if (!FlxG.keys.pressed.SHIFT) { - resyncVocals(); - } + if (FlxG.keys.pressed.W || FlxG.keys.pressed.S) + { + FlxG.sound.music.pause(); + vocals.pause(); - if (!startTimer.finished) - startTimer.active = true; - paused = false; + var daTime:Float = 700 * FlxG.elapsed; - #if windows - if (startTimer.finished) - { - DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses, iconRPC, true, songLength - Conductor.songPosition); + if (FlxG.keys.pressed.W) + { + FlxG.sound.music.time -= daTime; + } + else + FlxG.sound.music.time += daTime; + + vocals.time = FlxG.sound.music.time; + } } else { - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), iconRPC); + if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S) + { + FlxG.sound.music.pause(); + vocals.pause(); + + var daTime:Float = Conductor.stepCrochet * 2; + + if (FlxG.keys.justPressed.W) + { + FlxG.sound.music.time -= daTime; + } + else + FlxG.sound.music.time += daTime; + + vocals.time = FlxG.sound.music.time; + } } - #end } - super.closeSubState(); - } - + _song.bpm = tempBpm; - function resyncVocals():Void + /* if (FlxG.keys.justPressed.UP) + Conductor.changeBPM(Conductor.bpm + 1); + if (FlxG.keys.justPressed.DOWN) + Conductor.changeBPM(Conductor.bpm - 1); */ + + bpmTxt.text = bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 2)) + + " / " + + Std.string(FlxMath.roundDecimal(FlxG.sound.music.length / 1000, 2)) + + "\nSection: " + + curSection + + "\nCurStep: " + + curStep; + super.update(elapsed); + } + + function changeNoteSustain(value:Float):Void { + if (curSelectedNote != null) + { + if (curSelectedNote[2] != null) + { + curSelectedNote[2] += value; + curSelectedNote[2] = Math.max(curSelectedNote[2], 0); + } + } + + updateNoteUI(); + updateGrid(); + } + + override function beatHit() + { + trace('beat'); + + super.beatHit(); + if (!player2.animation.curAnim.name.startsWith("sing")) + { + player2.playAnim('idle'); + } + player1.dance(); + } + + function recalculateSteps():Int + { + var lastChange:BPMChangeEvent = { + stepTime: 0, + songTime: 0, + bpm: 0 + } + for (i in 0...Conductor.bpmChangeMap.length) + { + if (FlxG.sound.music.time > Conductor.bpmChangeMap[i].songTime) + lastChange = Conductor.bpmChangeMap[i]; + } + + curStep = lastChange.stepTime + Math.floor((FlxG.sound.music.time - lastChange.songTime) / Conductor.stepCrochet); + updateBeat(); + + return curStep; + } + + function resetSection(songBeginning:Bool = false):Void + { + updateGrid(); + + FlxG.sound.music.pause(); vocals.pause(); - FlxG.sound.music.play(); - Conductor.songPosition = FlxG.sound.music.time; - vocals.time = Conductor.songPosition; - vocals.play(); + // Basically old shit from changeSection??? + FlxG.sound.music.time = sectionStartTime(); - #if windows - DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); - #end + if (songBeginning) + { + FlxG.sound.music.time = 0; + curSection = 0; + } + + vocals.time = FlxG.sound.music.time; + updateCurStep(); + + updateGrid(); + updateSectionUI(); } - private var paused:Bool = false; - var startedCountdown:Bool = false; - var canPause:Bool = true; - - public static var songRate = 1.5; - - override public function update(elapsed:Float) + function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void { - #if !debug - perfectMode = false; - #end + trace('changing section' + sec); - #if windows - if (executeModchart && luaModchart != null && songStarted) + if (_song.notes[sec] != null) { - luaModchart.setVar('songPos',Conductor.songPosition); - luaModchart.setVar('hudZoom', camHUD.zoom); - luaModchart.setVar('cameraZoom',FlxG.camera.zoom); - luaModchart.executeState('update', [elapsed]); + trace('naw im not null'); + curSection = sec; - for (i in luaWiggles) + updateGrid(); + + if (updateMusic) { - trace('wiggle le gaming'); - i.update(elapsed); - } + FlxG.sound.music.pause(); + vocals.pause(); - /*for (i in 0...strumLineNotes.length) { - var member = strumLineNotes.members[i]; - member.x = luaModchart.getVar("strum" + i + "X", "float"); - member.y = luaModchart.getVar("strum" + i + "Y", "float"); - member.angle = luaModchart.getVar("strum" + i + "Angle", "float"); - }*/ - - FlxG.camera.angle = luaModchart.getVar('cameraAngle', 'float'); - camHUD.angle = luaModchart.getVar('camHudAngle','float'); - - if (luaModchart.getVar("showOnlyStrums",'bool')) - { - healthBarBG.visible = false; - kadeEngineWatermark.visible = false; - healthBar.visible = false; - iconP1.visible = false; - iconP2.visible = false; - scoreTxt.visible = false; - } - else - { - healthBarBG.visible = true; - kadeEngineWatermark.visible = true; - healthBar.visible = true; - iconP1.visible = true; - iconP2.visible = true; - scoreTxt.visible = true; - } - - var p1 = luaModchart.getVar("strumLine1Visible",'bool'); - var p2 = luaModchart.getVar("strumLine2Visible",'bool'); - - for (i in 0...4) - { - strumLineNotes.members[i].visible = p1; - if (i <= playerStrums.length) - playerStrums.members[i].visible = p2; - } - } - - #end - - if (currentFrames == FlxG.save.data.fpsCap) - { - for(i in 0...notesHitArray.length) - { - var cock:Date = notesHitArray[i]; - if (cock != null) - if (cock.getTime() + 2000 < Date.now().getTime()) - notesHitArray.remove(cock); - } - nps = Math.floor(notesHitArray.length / 2); - currentFrames = 0; - } - else - currentFrames++; - - 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) + /*var daNum:Int = 0; + var daLength:Float = 0; + while (daNum <= sec) { - updateTrainPos(); - trainFrameTiming = 0; - } - } - // phillyCityLights.members[curLight].alpha -= (Conductor.crochet / 1000) * FlxG.elapsed; - } + daLength += lengthBpmBullshit(); + daNum++; + }*/ - super.update(elapsed); - - scoreTxt.text = Ratings.CalculateRanking(songScore,songScoreDef,nps,accuracy); - 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()); + FlxG.sound.music.time = sectionStartTime(); + vocals.time = FlxG.sound.music.time; + updateCurStep(); } - else - openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); + + updateGrid(); + updateSectionUI(); } - - if (FlxG.keys.justPressed.SEVEN) - { - #if windows - DiscordClient.changePresence("Chart Editor", null, null, true); - #end - FlxG.switchState(new ChartingState()); - #if windows - if (luaModchart != null) - { - luaModchart.die(); - luaModchart = null; - } - #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; + trace('bro wtf I AM NULL'); + } - if (healthBar.percent > 80) - iconP2.animation.curAnim.curFrame = 1; - else - iconP2.animation.curAnim.curFrame = 0; + function copySection(?sectionNum:Int = 1) + { + var daSec = FlxMath.maxInt(curSection, sectionNum); - /* if (FlxG.keys.justPressed.NINE) - FlxG.switchState(new Charting()); */ - - #if debug - if (FlxG.keys.justPressed.EIGHT) + for (note in _song.notes[daSec - sectionNum].sectionNotes) { - FlxG.switchState(new AnimationDebug(SONG.player2)); - #if windows - if (luaModchart != null) - { - luaModchart.die(); - luaModchart = null; - } - #end + var strum = note[0] + Conductor.stepCrochet * (_song.notes[daSec].lengthInSteps * sectionNum); + + var copiedNote:Array = [strum, note[1], note[2]]; + _song.notes[daSec].sectionNotes.push(copiedNote); } + + updateGrid(); + } + + function updateSectionUI():Void + { + var sec = _song.notes[curSection]; + + stepperLength.value = sec.lengthInSteps; + check_mustHitSection.checked = sec.mustHitSection; + check_altAnim.checked = sec.altAnim; + check_changeBPM.checked = sec.changeBPM; + stepperSectionBPM.value = sec.bpm; + } + + function updateHeads():Void + { + if (check_mustHitSection.checked) + { + leftIcon.animation.play(_song.player1); + rightIcon.animation.play(_song.player2); + } + else + { + leftIcon.animation.play(_song.player2); + rightIcon.animation.play(_song.player1); + } + } + + function updateNoteUI():Void + { + if (curSelectedNote != null) + stepperSusLength.value = curSelectedNote[2]; + } + + function updateGrid():Void + { + remove(gridBG); + gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * _song.notes[curSection].lengthInSteps); + add(gridBG); + + remove(gridBlackLine); + gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK); + add(gridBlackLine); - #end - - if (startingSong) + while (curRenderedNotes.members.length > 0) { - if (startedCountdown) - { - Conductor.songPosition += FlxG.elapsed * 1000; - if (Conductor.songPosition >= 0) - startSong(); - } + curRenderedNotes.remove(curRenderedNotes.members[0], true); + } + + while (curRenderedSustains.members.length > 0) + { + curRenderedSustains.remove(curRenderedSustains.members[0], true); + } + + var sectionInfo:Array = _song.notes[curSection].sectionNotes; + + if (_song.notes[curSection].changeBPM && _song.notes[curSection].bpm > 0) + { + Conductor.changeBPM(_song.notes[curSection].bpm); + FlxG.log.add('CHANGED BPM!'); } else { - // Conductor.songPosition = FlxG.sound.music.time; - Conductor.songPosition += FlxG.elapsed * 1000; - /*@:privateAccess - { - FlxG.sound.music._channel. - }*/ - songPositionBar = Conductor.songPosition; - - 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; + // get last bpm + var daBPM:Int = _song.bpm; + for (i in 0...curSection) + if (_song.notes[i].changeBPM) + daBPM = _song.notes[i].bpm; + Conductor.changeBPM(daBPM); } - if (generatedMusic && PlayState.SONG.notes[Std.int(curStep / 16)] != null) - { - // Make sure Girlfriend cheers only for certain songs - if(allowedToHeadbang) + /* // PORT BULLSHIT, INCASE THERE'S NO SUSTAIN DATA FOR A NOTE + for (sec in 0..._song.notes.length) { - // Don't animate GF if something else is already animating her (eg. train passing) - if(gf.animation.curAnim.name == 'danceLeft' || gf.animation.curAnim.name == 'danceRight' || gf.animation.curAnim.name == 'idle') + for (notesse in 0..._song.notes[sec].sectionNotes.length) { - // Per song treatment since some songs will only have the 'Hey' at certain times - switch(curSong) + if (_song.notes[sec].sectionNotes[notesse][2] == null) { - case 'Philly': - { - // General duration of the song - if(curBeat < 250) - { - // Beats to skip or to stop GF from cheering - if(curBeat != 184 && curBeat != 216) - { - if(curBeat % 16 == 8) - { - // Just a garantee that it'll trigger just once - if(!triggeredAlready) - { - gf.playAnim('cheer'); - triggeredAlready = true; - } - }else triggeredAlready = false; - } - } - } - case 'Bopeebo': - { - // Where it starts || where it ends - if(curBeat > 5 && curBeat < 130) - { - if(curBeat % 8 == 7) - { - if(!triggeredAlready) - { - gf.playAnim('cheer'); - triggeredAlready = true; - } - }else triggeredAlready = false; - } - } - case 'Blammed': - { - if(curBeat > 30 && curBeat < 190) - { - if(curBeat < 90 || curBeat > 128) - { - if(curBeat % 4 == 2) - { - if(!triggeredAlready) - { - gf.playAnim('cheer'); - triggeredAlready = true; - } - }else triggeredAlready = false; - } - } - } - case 'Cocoa': - { - if(curBeat < 170) - { - if(curBeat < 65 || curBeat > 130 && curBeat < 145) - { - if(curBeat % 16 == 15) - { - if(!triggeredAlready) - { - gf.playAnim('cheer'); - triggeredAlready = true; - } - }else triggeredAlready = false; - } - } - } - case 'Eggnog': - { - if(curBeat > 10 && curBeat != 111 && curBeat < 220) - { - if(curBeat % 8 == 7) - { - if(!triggeredAlready) - { - gf.playAnim('cheer'); - triggeredAlready = true; - } - }else triggeredAlready = false; - } - } + trace('SUS NULL'); + _song.notes[sec].sectionNotes[notesse][2] = 0; } } } - - #if windows - if (luaModchart != null) - luaModchart.setVar("mustHit",PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection); - #end + */ - if (camFollow.x != dad.getMidpoint().x + 150 && !PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection) - { - var offsetX = 0; - var offsetY = 0; - #if windows - if (luaModchart != null) - { - offsetX = luaModchart.getVar("followXOffset", "float"); - offsetY = luaModchart.getVar("followYOffset", "float"); - } - #end - camFollow.setPosition(dad.getMidpoint().x + 150 + offsetX, dad.getMidpoint().y - 100 + offsetY); - #if windows - if (luaModchart != null) - luaModchart.executeState('playerTwoTurn', []); - #end - // 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 (PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection && camFollow.x != boyfriend.getMidpoint().x - 100) - { - var offsetX = 0; - var offsetY = 0; - #if windows - if (luaModchart != null) - { - offsetX = luaModchart.getVar("followXOffset", "float"); - offsetY = luaModchart.getVar("followYOffset", "float"); - } - #end - camFollow.setPosition(boyfriend.getMidpoint().x - 100 + offsetX, boyfriend.getMidpoint().y - 100 + offsetY); - - #if windows - if (luaModchart != null) - luaModchart.executeState('playerOneTurn', []); - #end - - 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 (camZooming) + for (i in sectionInfo) { - FlxG.camera.zoom = FlxMath.lerp(defaultCamZoom, FlxG.camera.zoom, 0.95); - camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, 0.95); - } + var daNoteInfo = i[1]; + var daStrumTime = i[0]; + var daSus = i[2]; - FlxG.watch.addQuick("beatShit", curBeat); - FlxG.watch.addQuick("stepShit", curStep); - if (loadRep) // rep debug - { - FlxG.watch.addQuick('rep rpesses',repPresses); - FlxG.watch.addQuick('rep releases',repReleases); - // FlxG.watch.addQuick('Queued',inputsQueued); - } + var note:Note = new Note(daStrumTime, daNoteInfo % 4); + note.sustainLength = daSus; + note.setGraphicSize(GRID_SIZE, GRID_SIZE); + note.updateHitbox(); + note.x = Math.floor(daNoteInfo * GRID_SIZE); + note.y = Math.floor(getYfromStrum((daStrumTime - sectionStartTime()) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps))); - if (curSong == 'Fresh') - { - switch (curBeat) + if (curSelectedNote != null) + if (curSelectedNote[0] == note.strumTime) + lastNote = note; + + curRenderedNotes.add(note); + + if (daSus > 0) { - 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()); + var sustainVis:FlxSprite = new FlxSprite(note.x + (GRID_SIZE / 2), + note.y + GRID_SIZE).makeGraphic(8, Math.floor(FlxMath.remapToRange(daSus, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps, 0, gridBG.height))); + curRenderedSustains.add(sustainVis); } } - - if (curSong == 'Bopeebo') - { - switch (curBeat) - { - case 128, 129, 130: - vocals.volume = 0; - // FlxG.sound.music.stop(); - // FlxG.switchState(new PlayState()); - } - } - - 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)); - - #if windows - // Game Over doesn't get his own variable because it's only used here - DiscordClient.changePresence("GAME OVER -- " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy),"\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); - #end - - // FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); - } - - if (unspawnNotes[0] != null) - { - if (unspawnNotes[0].strumTime - Conductor.songPosition < 3500) - { - 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) - { - - // instead of doing stupid y > FlxG.height - // we be men and actually calculate the time :) - if (daNote.tooLate) - { - daNote.active = false; - daNote.visible = false; - } - else - { - daNote.visible = true; - daNote.active = true; - } - - if (!daNote.modifiedByLua) - { - if (FlxG.save.data.downscroll) - { - if (daNote.mustPress) - daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); - else - daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); - if(daNote.isSustainNote) - { - // Remember = minus makes notes go up, plus makes them go down - if(daNote.animation.curAnim.name.endsWith('end') && daNote.prevNote != null) - daNote.y += daNote.prevNote.height; - else - daNote.y += daNote.height / 2; - - if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= (strumLine.y + Note.swagWidth / 2)) - { - // Clip to strumline - var swagRect = new FlxRect(0, 0, daNote.frameWidth * 2, daNote.frameHeight * 2); - swagRect.height = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + Note.swagWidth / 2 - daNote.y) / daNote.scale.y; - swagRect.y = daNote.frameHeight - swagRect.height; - - daNote.clipRect = swagRect; - } - } - }else - { - if (daNote.mustPress) - daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); - else - daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); - if(daNote.isSustainNote) - { - daNote.y -= daNote.height / 2; - - if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y + daNote.offset.y * daNote.scale.y <= (strumLine.y + Note.swagWidth / 2)) - { - // Clip to strumline - var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y); - swagRect.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + Note.swagWidth / 2 - daNote.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 2: - dad.playAnim('singUP' + altAnim, true); - case 3: - dad.playAnim('singRIGHT' + altAnim, true); - case 1: - dad.playAnim('singDOWN' + altAnim, true); - case 0: - dad.playAnim('singLEFT' + altAnim, true); - } - - #if windows - if (luaModchart != null) - luaModchart.executeState('playerTwoSing', [Math.abs(daNote.noteData), Conductor.songPosition]); - #end - - dad.holdTimer = 0; - - if (SONG.needsVoices) - vocals.volume = 1; - - daNote.active = false; - - daNote.kill(); - notes.remove(daNote, true); - daNote.destroy(); - } - - if (daNote.mustPress && !daNote.modifiedByLua) - { - daNote.visible = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].visible; - daNote.x = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].x; - if (!daNote.isSustainNote) - daNote.angle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle; - daNote.alpha = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].alpha; - } - else if (!daNote.wasGoodHit && !daNote.modifiedByLua) - { - daNote.visible = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].visible; - daNote.x = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].x; - if (!daNote.isSustainNote) - daNote.angle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].angle; - daNote.alpha = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].alpha; - } - - - - if (daNote.isSustainNote) - daNote.x += daNote.width / 2 + 17; - - - //trace(daNote.y); - // WIP interpolation shit? Need to fix the pause issue - // daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed)); - - if ((daNote.mustPress && daNote.tooLate && !FlxG.save.data.downscroll || daNote.mustPress && daNote.tooLate && FlxG.save.data.downscroll) && daNote.mustPress) - { - if (daNote.isSustainNote && daNote.wasGoodHit) - { - daNote.kill(); - notes.remove(daNote, true); - daNote.destroy(); - } - else - { - health -= 0.075; - vocals.volume = 0; - if (theFunne) - noteMiss(daNote.noteData, daNote); - } - - 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 + private function addSection(lengthInSteps:Int = 16):Void { - if (!loadRep) - rep.SaveReplay(); + var sec:SwagSection = { + lengthInSteps: lengthInSteps, + bpm: _song.bpm, + changeBPM: false, + mustHitSection: true, + sectionNotes: [], + typeOfSection: 0, + altAnim: false + }; - #if windows - if (luaModchart != null) - { - luaModchart.die(); - luaModchart = null; - } - #end + _song.notes.push(sec); + } - canPause = false; - FlxG.sound.music.volume = 0; - vocals.volume = 0; - if (SONG.validScore) + function selectNote(note:Note):Void + { + var swagNum:Int = 0; + + for (i in _song.notes[curSection].sectionNotes) { - #if !switch - Highscore.saveScore(SONG.song, Math.round(songScore), storyDifficulty); - #end + if (i.strumTime == note.strumTime && i.noteData % 4 == note.noteData) + { + curSelectedNote = _song.notes[curSection].sectionNotes[swagNum]; + } + + swagNum += 1; } - if (offsetTesting) + updateGrid(); + updateNoteUI(); + } + + + function deleteNote(note:Note):Void { - FlxG.sound.playMusic(Paths.music('freakyMenu')); - offsetTesting = false; - LoadingState.loadAndSwitchState(new OptionsMenu()); - FlxG.save.data.offset = offsetTest; + lastNote = note; + for (i in _song.notes[curSection].sectionNotes) + { + if (i[0] == note.strumTime && i[1] % 4 == note.noteData) + { + _song.notes[curSection].sectionNotes.remove(i); + } + } + + updateGrid(); } + + function clearSection():Void + { + _song.notes[curSection].sectionNotes = []; + + updateGrid(); + } + + function clearSong():Void + { + for (daSection in 0..._song.notes.length) + { + _song.notes[daSection].sectionNotes = []; + } + + updateGrid(); + } + + private function addNote(?n:Note):Void + { + var noteStrum = getStrumTime(dummyArrow.y) + sectionStartTime(); + var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE); + var noteSus = 0; + + if (n != null) + _song.notes[curSection].sectionNotes.push([n.strumTime, n.noteData, n.sustainLength]); else - { - if (isStoryMode) - { - campaignScore += Math.round(songScore); + _song.notes[curSection].sectionNotes.push([noteStrum, noteData, noteSus]); - storyPlaylist.remove(storyPlaylist[0]); + var thingy = _song.notes[curSection].sectionNotes[_song.notes[curSection].sectionNotes.length - 1]; - if (storyPlaylist.length <= 0) - { - FlxG.sound.playMusic(Paths.music('freakyMenu')); + curSelectedNote = thingy; - transIn = FlxTransitionableState.defaultTransIn; - transOut = FlxTransitionableState.defaultTransOut; + updateGrid(); + updateNoteUI(); - FlxG.switchState(new StoryMenuState()); - - #if windows - if (luaModchart != null) - { - luaModchart.die(); - luaModchart = null; - } - #end - - // if () - StoryMenuState.weekUnlocked[Std.int(Math.min(storyWeek + 1, StoryMenuState.weekUnlocked.length - 1))] = true; - - if (SONG.validScore) - { - NGio.unlockMedal(60961); - 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()); - } - } + autosaveSong(); } - - var endingSong:Bool = false; - - var hits:Array = []; - var offsetTest:Float = 0; - - var timeShown = 0; - var currentTimingShown:FlxText = null; - - private function popUpScore(daNote:Note):Void - { - var noteDiff:Float = Math.abs(Conductor.songPosition - daNote.strumTime); - var wife:Float = EtternaFunctions.wife3(noteDiff, Conductor.timeScale); - // 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; - coolText.y -= 350; - coolText.cameras = [camHUD]; - // - - var rating:FlxSprite = new FlxSprite(); - var score:Float = 350; - - if (FlxG.save.data.accuracyMod == 1) - totalNotesHit += wife; - - var daRating = daNote.rating; - - switch(daRating) - { - case 'shit': - score = -300; - combo = 0; - misses++; - health -= 0.2; - ss = false; - shits++; - if (FlxG.save.data.accuracyMod == 0) - totalNotesHit += 0.25; - case 'bad': - daRating = 'bad'; - score = 0; - health -= 0.06; - ss = false; - bads++; - if (FlxG.save.data.accuracyMod == 0) - totalNotesHit += 0.50; - case 'good': - daRating = 'good'; - score = 200; - ss = false; - goods++; - if (health < 2) - health += 0.04; - if (FlxG.save.data.accuracyMod == 0) - totalNotesHit += 0.75; - case 'sick': - if (health < 2) - health += 0.1; - if (FlxG.save.data.accuracyMod == 0) - totalNotesHit += 1; - sicks++; - } - - // trace('Wife accuracy loss: ' + wife + ' | Rating: ' + daRating + ' | Score: ' + score + ' | Weight: ' + (1 - wife)); - - if (daRating != 'shit' || daRating != 'bad') - { - - - songScore += Math.round(score); - songScoreDef += Math.round(ConvertScore.convertScore(noteDiff)); - - /* 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.y -= 50; - rating.x = coolText.x - 125; - - if (FlxG.save.data.changedHit) - { - rating.x = FlxG.save.data.changedHitX; - rating.y = FlxG.save.data.changedHitY; - } - rating.acceleration.y = 550; - rating.velocity.y -= FlxG.random.int(140, 175); - rating.velocity.x -= FlxG.random.int(0, 10); - - - var msTiming = HelperFunctions.truncateFloat(noteDiff, 3); - - if (currentTimingShown != null) - remove(currentTimingShown); - - currentTimingShown = new FlxText(0,0,0,"0ms"); - timeShown = 0; - switch(daRating) - { - case 'shit' | 'bad': - currentTimingShown.color = FlxColor.RED; - case 'good': - currentTimingShown.color = FlxColor.GREEN; - case 'sick': - currentTimingShown.color = FlxColor.CYAN; - } - currentTimingShown.borderStyle = OUTLINE; - currentTimingShown.borderSize = 1; - currentTimingShown.borderColor = FlxColor.BLACK; - currentTimingShown.text = msTiming + "ms"; - currentTimingShown.size = 20; - - if (msTiming >= 0.03 && offsetTesting) - { - //Remove Outliers - hits.shift(); - hits.shift(); - hits.shift(); - hits.pop(); - hits.pop(); - hits.pop(); - hits.push(msTiming); - - var total = 0.0; - - for(i in hits) - total += i; - - - - offsetTest = HelperFunctions.truncateFloat(total / hits.length,2); - } - - if (currentTimingShown.alpha != 1) - currentTimingShown.alpha = 1; - - add(currentTimingShown); - - - - var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); - comboSpr.screenCenter(); - comboSpr.x = rating.x; - comboSpr.y = rating.y + 100; - comboSpr.acceleration.y = 600; - comboSpr.velocity.y -= 150; - - currentTimingShown.screenCenter(); - currentTimingShown.x = comboSpr.x + 100; - currentTimingShown.y = rating.y + 100; - currentTimingShown.acceleration.y = 600; - currentTimingShown.velocity.y -= 150; - - comboSpr.velocity.x += FlxG.random.int(1, 10); - currentTimingShown.velocity.x += comboSpr.velocity.x; - 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)); - } - - currentTimingShown.updateHitbox(); - comboSpr.updateHitbox(); - rating.updateHitbox(); - - currentTimingShown.cameras = [camHUD]; - comboSpr.cameras = [camHUD]; - rating.cameras = [camHUD]; - - var seperatedScore:Array = []; - - var comboSplit:Array = (combo + "").split(''); - - if (comboSplit.length == 2) - seperatedScore.push(0); // make sure theres a 0 in front or it looks weird lol! - - for(i in 0...comboSplit.length) - { - var str:String = comboSplit[i]; - seperatedScore.push(Std.parseInt(str)); - } - - 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 = rating.x + (43 * daLoop) - 50; - numScore.y = rating.y + 100; - numScore.cameras = [camHUD]; - - 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, - onUpdate: function(tween:FlxTween) - { - if (currentTimingShown != null) - currentTimingShown.alpha -= 0.02; - timeShown++; - } - }); - - FlxTween.tween(comboSpr, {alpha: 0}, 0.2, { - onComplete: function(tween:FlxTween) - { - coolText.destroy(); - comboSpr.destroy(); - if (currentTimingShown != null && timeShown >= 20) - { - remove(currentTimingShown); - currentTimingShown = null; - } - rating.destroy(); - }, - startDelay: Conductor.crochet * 0.001 - }); - - curSection += 1; - } - } - - public function NearlyEquals(value1:Float, value2:Float, unimportantDifference:Float = 10):Bool - { - return Math.abs(FlxMath.roundDecimal(value1, 1) - FlxMath.roundDecimal(value2, 1)) < unimportantDifference; - } - - var upHold:Bool = false; - var downHold:Bool = false; - var rightHold:Bool = false; - var leftHold:Bool = false; - - private function keyShit():Void // I've invested in emma stocks - { - // control arrays, order L D R U - var holdArray:Array = [controls.LEFT, controls.DOWN, controls.UP, controls.RIGHT]; - var pressArray:Array = [ - controls.LEFT_P, - controls.DOWN_P, - controls.UP_P, - controls.RIGHT_P - ]; - var releaseArray:Array = [ - controls.LEFT_R, - controls.DOWN_R, - controls.UP_R, - controls.RIGHT_R - ]; - - // HOLDS, check for sustain notes - if (holdArray.contains(true) && /*!boyfriend.stunned && */ generatedMusic) - { - notes.forEachAlive(function(daNote:Note) - { - if (daNote.isSustainNote && daNote.canBeHit && daNote.mustPress && holdArray[daNote.noteData]) - goodNoteHit(daNote); - }); - } - - // PRESSES, check for note hits - if (pressArray.contains(true) && /*!boyfriend.stunned && */ generatedMusic) - { - boyfriend.holdTimer = 0; - - var possibleNotes:Array = []; // notes that can be hit - var directionList:Array = []; // directions that can be hit - var dumbNotes:Array = []; // notes to kill later - - notes.forEachAlive(function(daNote:Note) - { - if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit) - { - if (directionList.contains(daNote.noteData)) - { - for (coolNote in possibleNotes) - { - if (coolNote.noteData == daNote.noteData && Math.abs(daNote.strumTime - coolNote.strumTime) < 10) - { // if it's the same note twice at < 10ms distance, just delete it - // EXCEPT u cant delete it in this loop cuz it fucks with the collection lol - dumbNotes.push(daNote); - break; - } - else if (coolNote.noteData == daNote.noteData && daNote.strumTime < coolNote.strumTime) - { // if daNote is earlier than existing note (coolNote), replace - possibleNotes.remove(coolNote); - possibleNotes.push(daNote); - break; - } - } - } - else - { - possibleNotes.push(daNote); - directionList.push(daNote.noteData); - } - } - }); - - for (note in dumbNotes) - { - FlxG.log.add("killing dumb ass note at " + note.strumTime); - note.kill(); - notes.remove(note, true); - note.destroy(); - } - - possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime)); - - var dontCheck = false; - - for (i in 0...pressArray.length) - { - if (pressArray[i] && !directionList.contains(i)) - dontCheck = true; - } - - if (perfectMode) - goodNoteHit(possibleNotes[0]); - else if (possibleNotes.length > 0 && !dontCheck) - { - if (!FlxG.save.data.ghost) - { - for (shit in 0...pressArray.length) - { // if a direction is hit that shouldn't be - if (pressArray[shit] && !directionList.contains(shit)) - noteMiss(shit, null); - } - } - for (coolNote in possibleNotes) - { - if (pressArray[coolNote.noteData]) - { - if (mashViolations != 0) - mashViolations--; - scoreTxt.color = FlxColor.WHITE; - goodNoteHit(coolNote); - } - } - } - else if (!FlxG.save.data.ghost) - { - for (shit in 0...pressArray.length) - if (pressArray[shit]) - noteMiss(shit, null); - } - - if (dontCheck && possibleNotes.length > 0 && FlxG.save.data.ghost) - { - if (mashViolations > 4) - { - trace('mash violations ' + mashViolations); - scoreTxt.color = FlxColor.RED; - noteMiss(0,null); - } - else - mashViolations++; - } - - } - - if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && !holdArray.contains(true)) - { - if (boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss')) - { - boyfriend.playAnim('idle'); - } - } - - playerStrums.forEach(function(spr:FlxSprite) - { - if (pressArray[spr.ID] && spr.animation.curAnim.name != 'confirm') - spr.animation.play('pressed'); - if (!holdArray[spr.ID]) - 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, daNote:Note):Void + function getStrumTime(yPos:Float):Float { - if (!boyfriend.stunned) - { - health -= 0.04; - if (combo > 5 && gf.animOffsets.exists('sad')) - { - gf.playAnim('sad'); - } - combo = 0; - misses++; - - //var noteDiff:Float = Math.abs(daNote.strumTime - Conductor.songPosition); - //var wife:Float = EtternaFunctions.wife3(noteDiff, FlxG.save.data.etternaMode ? 1 : 1.7); - - if (FlxG.save.data.accuracyMod == 1) - totalNotesHit -= 1; - - 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'); - - 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); - } - - #if windows - if (luaModchart != null) - luaModchart.executeState('playerOneMiss', [direction, Conductor.songPosition]); - #end - - - updateAccuracy(); - } + return FlxMath.remapToRange(yPos, gridBG.y, gridBG.y + gridBG.height, 0, 16 * Conductor.stepCrochet); } - /*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 (upP) - noteMiss(2); - if (rightP) - noteMiss(3); - if (downP) - noteMiss(1); - updateAccuracy(); - } - */ - function updateAccuracy() - { - totalPlayed += 1; - accuracy = Math.max(0,totalNotesHit / totalPlayed * 100); - accuracyDefault = Math.max(0, totalNotesHitDefault / totalPlayed * 100); - } - - - function getKeyPresses(note:Note):Int + function getYfromStrum(strumTime:Float):Float { - var possibleNotes:Array = []; // copypasted but you already know that + return FlxMath.remapToRange(strumTime, 0, 16 * Conductor.stepCrochet, gridBG.y, gridBG.y + gridBG.height); + } - notes.forEachAlive(function(daNote:Note) + /* + function calculateSectionLengths(?sec:SwagSection):Int { - if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate) + var daLength:Int = 0; + + for (i in _song.notes) { - possibleNotes.push(daNote); - possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime)); + var swagLength = i.lengthInSteps; + + if (i.typeOfSection == Section.COPYCAT) + swagLength * 2; + + daLength += swagLength; + + if (sec != null && sec == i) + { + trace('swag loop??'); + break; + } } + + return daLength; + }*/ + private var daSpacing:Float = 0.3; + + function loadLevel():Void + { + trace(_song.notes); + } + + function getNotes():Array + { + var noteData:Array = []; + + for (i in _song.notes) + { + noteData.push(i.sectionNotes); + } + + return noteData; + } + + function loadJson(song:String):Void + { + PlayState.SONG = Song.loadFromJson(song.toLowerCase(), song.toLowerCase()); + LoadingState.loadAndSwitchState(new ChartingState()); + } + + function loadAutosave():Void + { + PlayState.SONG = Song.parseJSONshit(FlxG.save.data.autosave); + LoadingState.loadAndSwitchState(new ChartingState()); + } + + function autosaveSong():Void + { + FlxG.save.data.autosave = Json.stringify({ + "song": _song }); - if (possibleNotes.length == 1) - return possibleNotes.length + 1; - return possibleNotes.length; + FlxG.save.flush(); } - - var mashing:Int = 0; - var mashViolations:Int = 0; - var etternaModeScore:Int = 0; - - function noteCheck(controlArray:Array, note:Note):Void // sorry lol - { - var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition); - - note.rating = Ratings.CalculateRating(noteDiff); - - if (loadRep) - { - if (controlArray[note.noteData]) - goodNoteHit(note, false); - else if (rep.replay.keyPresses.length > repPresses && !controlArray[note.noteData]) - { - if (NearlyEquals(note.strumTime,rep.replay.keyPresses[repPresses].time, 4)) - { - goodNoteHit(note, false); - } - } - } - else if (controlArray[note.noteData]) - { - - goodNoteHit(note, (mashing > getKeyPresses(note))); - - /*if (mashing > getKeyPresses(note) && mashViolations <= 2) - { - mashViolations++; - - goodNoteHit(note, (mashing > getKeyPresses(note))); - } - else if (mashViolations > 2) - { - // this is bad but fuck you - playerStrums.members[0].animation.play('static'); - playerStrums.members[1].animation.play('static'); - playerStrums.members[2].animation.play('static'); - playerStrums.members[3].animation.play('static'); - health -= 0.4; - trace('mash ' + mashing); - if (mashing != 0) - mashing = 0; - } - else - goodNoteHit(note, false);*/ - - } - } - - var nps:Int = 0; - - function goodNoteHit(note:Note, resetMashViolation = true):Void - { - - if (mashing != 0) - mashing = 0; - - var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition); - - note.rating = Ratings.CalculateRating(noteDiff); - - if (!note.isSustainNote) - notesHitArray.push(Date.now()); - - if (!resetMashViolation && mashViolations >= 1) - mashViolations--; - - if (mashViolations < 0) - mashViolations = 0; - - if (!note.wasGoodHit) - { - if (!note.isSustainNote) - { - popUpScore(note); - combo += 1; - } - else - totalNotesHit += 1; - - - switch (note.noteData) - { - case 2: - boyfriend.playAnim('singUP', true); - case 3: - boyfriend.playAnim('singRIGHT', true); - case 1: - boyfriend.playAnim('singDOWN', true); - case 0: - boyfriend.playAnim('singLEFT', true); - } - - #if windows - if (luaModchart != null) - luaModchart.executeState('playerOneSing', [note.noteData, Conductor.songPosition]); - #end - - - if (!loadRep) - playerStrums.forEach(function(spr:FlxSprite) - { - if (Math.abs(note.noteData) == spr.ID) - { - spr.animation.play('confirm', true); - } - }); - - note.wasGoodHit = true; - vocals.volume = 1; - - note.kill(); - notes.remove(note, true); - note.destroy(); - - updateAccuracy(); - } - } - - - var fastCarCanDrive:Bool = true; - - function resetFastCar():Void + private function saveLevel() { - if(FlxG.save.data.distractions){ - fastCar.x = -12600; - fastCar.y = FlxG.random.int(140, 250); - fastCar.velocity.x = 0; - fastCarCanDrive = true; + var json = { + "song": _song + }; + + var data:String = Json.stringify(json); + + if ((data != null) && (data.length > 0)) + { + _file = new FileReference(); + _file.addEventListener(Event.COMPLETE, onSaveComplete); + _file.addEventListener(Event.CANCEL, onSaveCancel); + _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file.save(data.trim(), _song.song.toLowerCase() + ".json"); } } - function fastCarDrive() + function onSaveComplete(_):Void { - if(FlxG.save.data.distractions){ - 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(); - }); - } + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.notice("Successfully saved LEVEL DATA."); } - var trainMoving:Bool = false; - var trainFrameTiming:Float = 0; - - var trainCars:Int = 8; - var trainFinishing:Bool = false; - var trainCooldown:Int = 0; - - function trainStart():Void + /** + * Called when the save file dialog is cancelled. + */ + function onSaveCancel(_):Void { - if(FlxG.save.data.distractions){ - trainMoving = true; - if (!trainSound.playing) - trainSound.play(true); - } + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; } - var startedMoving:Bool = false; - - function updateTrainPos():Void + /** + * Called if there is an error while saving the gameplay recording. + */ + function onSaveError(_):Void { - if(FlxG.save.data.distractions){ - 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(); - } - } - + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.error("Problem saving Level data"); } - - function trainReset():Void - { - if(FlxG.save.data.distractions){ - 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 windows - if (executeModchart && luaModchart != null) - { - luaModchart.setVar('curStep',curStep); - luaModchart.executeState('stepHit',[curStep]); - } - #end - - if (dad.curCharacter == 'spooky' && curStep % 4 == 2) - { - // dad.dance(); - } - - - // yes this updates every step. - // yes this is bad - // but i'm doing it to update misses and accuracy - #if windows - // 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 + ") " + Ratings.GenerateLetterRank(accuracy), "Acc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC,true, songLength - Conductor.songPosition); - #end - - } - - var lightningStrikeBeat:Int = 0; - var lightningOffset:Int = 8; - - override function beatHit() - { - super.beatHit(); - - if (generatedMusic) - { - notes.sort(FlxSort.byY, (FlxG.save.data.downscroll ? FlxSort.ASCENDING : FlxSort.DESCENDING)); - } - - #if windows - if (executeModchart && luaModchart != null) - { - luaModchart.setVar('curBeat',curBeat); - luaModchart.executeState('beatHit',[curBeat]); - } - #end - - 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 - - // Commented out until a reason to bring this back arises in the future - /* if (SONG.notes[Math.floor(curStep / 16)].mustHitSection) - dad.dance(); */ - - if(dad.animation.curAnim.name.startsWith('sing')) - if(dad.animation.finished) - dad.dance(); - else - 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': - if(FlxG.save.data.distractions){ - bgGirls.dance(); - } - - case 'mall': - if(FlxG.save.data.distractions){ - upperBoppers.animation.play('bop', true); - bottomBoppers.animation.play('bop', true); - santa.animation.play('idle', true); - } - - case 'limo': - if(FlxG.save.data.distractions){ - grpLimoDancers.forEach(function(dancer:BackgroundDancer) - { - dancer.dance(); - }); - - if (FlxG.random.bool(10) && fastCarCanDrive) - fastCarDrive(); - } - case "philly": - if(FlxG.save.data.distractions){ - 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) - { - if(FlxG.save.data.distractions){ - trainCooldown = FlxG.random.int(-4, 0); - trainStart(); - } - } - } - - if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset) - { - if(FlxG.save.data.distractions){ - lightningStrikeShit(); - } - } - } - - var curLight:Int = 0; } From 64b98d68f440d3281020f0664cf964b14cfc7223 Mon Sep 17 00:00:00 2001 From: Prokube <68293280+prokube@users.noreply.github.com> Date: Tue, 4 May 2021 06:27:18 -0700 Subject: [PATCH 2/4] fuckin stupid it was 8:30 PM and for my standards that's late --- source/ChartingState.hx | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/source/ChartingState.hx b/source/ChartingState.hx index ddd4478..104763f 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -164,7 +164,7 @@ class ChartingState extends MusicBeatState var tabs = [ {name: "Song", label: 'Song'}, {name: "Section", label: 'Section'}, - {name: "Note", label: 'Note'}, + {name: "Note", label: 'Note Data'}, {name: "Assets", label: 'Assets'} ]; @@ -227,7 +227,7 @@ class ChartingState extends MusicBeatState }); - var restart = new FlxButton(10,140,"Reset", function() + var restart = new FlxButton(10,140,"Reset Chart", function() { for (ii in 0..._song.notes.length) { @@ -245,10 +245,14 @@ class ChartingState extends MusicBeatState stepperSpeed.value = _song.speed; stepperSpeed.name = 'song_speed'; + var stepperSpeedLabel = new FlxText(74,80,'Scroll Speed'); + var stepperBPM:FlxUINumericStepper = new FlxUINumericStepper(10, 65, 0.1, 1, 1.0, 5000.0, 1); stepperBPM.value = Conductor.bpm; stepperBPM.name = 'song_bpm'; + var stepperBPMLabel = new FlxText(74,65,'BPM'); + var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); var gfVersions:Array = CoolUtil.coolTextFile(Paths.txt('gfVersionList')); var stages:Array = CoolUtil.coolTextFile(Paths.txt('stageList')); @@ -260,30 +264,39 @@ class ChartingState extends MusicBeatState }); player1DropDown.selectedLabel = _song.player1; + var player1Label = new FlxText(10,80,64,'Player 1'); + var player2DropDown = new FlxUIDropDownMenu(140, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) { _song.player2 = characters[Std.parseInt(character)]; }); - player2DropDown.selectedLabel = _song.player2; + var player2Label = new FlxText(140,80,64,'Player 2'); + var gfVersionDropDown = new FlxUIDropDownMenu(10, 200, FlxUIDropDownMenu.makeStrIdLabelArray(gfVersions, true), function(gfVersion:String) { _song.gfVersion = gfVersions[Std.parseInt(gfVersion)]; }); - gfVersionDropDown.selectedLabel = _song.gfVersion; + gfVersionDropDown.selectedLabel = _song.gfVersion; + + var gfVersionLabel = new FlxText(10,180,64,'Girlfriend'); var stageDropDown = new FlxUIDropDownMenu(140, 200, FlxUIDropDownMenu.makeStrIdLabelArray(stages, true), function(stage:String) { _song.stage = stages[Std.parseInt(stage)]; }); - stageDropDown.selectedLabel = _song.stage; + stageDropDown.selectedLabel = _song.stage; + + var stageLabel = new FlxText(140,180,64,'Stage'); var noteStyleDropDown = new FlxUIDropDownMenu(10, 300, FlxUIDropDownMenu.makeStrIdLabelArray(noteStyles, true), function(noteStyle:String) { _song.noteStyle = noteStyles[Std.parseInt(noteStyle)]; }); - noteStyleDropDown.selectedLabel = _song.noteStyle; + noteStyleDropDown.selectedLabel = _song.noteStyle; + + var noteStyleLabel = new FlxText(10,280,64,'Note Skin'); var tab_group_song = new FlxUI(null, UI_box); tab_group_song.name = "Song"; @@ -296,15 +309,22 @@ class ChartingState extends MusicBeatState tab_group_song.add(reloadSongJson); tab_group_song.add(loadAutosaveBtn); tab_group_song.add(stepperBPM); + tab_group_song.add(stepperBPMLabel); tab_group_song.add(stepperSpeed); + tab_group_song.add(stepperSpeedLabel); var tab_group_assets = new FlxUI(null, UI_box); tab_group_assets.name = "Assets"; tab_group_assets.add(noteStyleDropDown); + tab_group_assets.add(noteStyleLabel); tab_group_assets.add(gfVersionDropDown); + tab_group_assets.add(gfVersionLabel); tab_group_assets.add(stageDropDown); + tab_group_assets.add(stageLabel); tab_group_assets.add(player1DropDown); tab_group_assets.add(player2DropDown); + tab_group_assets.add(player1Label); + tab_group_assets.add(player2Label); UI_box.addGroup(tab_group_song); UI_box.addGroup(tab_group_assets); @@ -392,10 +412,13 @@ class ChartingState extends MusicBeatState stepperSusLength.value = 0; stepperSusLength.name = 'note_susLength'; - var applyLength:FlxButton = new FlxButton(100, 10, 'Apply'); + var stepperSusLengthLabel = new FlxText(74,10,'Note Sustain Length'); + + var applyLength:FlxButton = new FlxButton(10, 100, 'Apply Data'); tab_group_note.add(writingNotesText); tab_group_note.add(stepperSusLength); + tab_group_note.add(stepperSusLengthLabel); tab_group_note.add(applyLength); UI_box.addGroup(tab_group_note); From e434c9c504a109051f3ced56ae384e25d0f1000a Mon Sep 17 00:00:00 2001 From: Prokube <68293280+prokube@users.noreply.github.com> Date: Tue, 4 May 2021 06:32:08 -0700 Subject: [PATCH 3/4] lol sorry --- source/PlayState.hx | 4341 +++++++++++++++++++++++++++++++------------ 1 file changed, 3165 insertions(+), 1176 deletions(-) diff --git a/source/PlayState.hx b/source/PlayState.hx index 104763f..6d7d5cf 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -1,1347 +1,3336 @@ package; -import flixel.addons.ui.FlxUIText; -import haxe.zip.Writer; -import Conductor.BPMChangeEvent; +import haxe.Exception; +import openfl.geom.Matrix; +import openfl.display.BitmapData; +import openfl.utils.AssetType; +import lime.graphics.Image; +import flixel.graphics.FlxGraphic; +import openfl.utils.AssetManifest; +import openfl.utils.AssetLibrary; +import flixel.system.FlxAssets; + +import lime.app.Application; +import lime.media.AudioContext; +import lime.media.AudioManager; +import openfl.Lib; 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.ui.FlxInputText; -import flixel.addons.ui.FlxUI9SliceSprite; -import flixel.addons.ui.FlxUI; -import flixel.addons.ui.FlxUICheckBox; -import flixel.addons.ui.FlxUIDropDownMenu; -import flixel.addons.ui.FlxUIInputText; -import flixel.addons.ui.FlxUINumericStepper; -import flixel.addons.ui.FlxUITabMenu; -import flixel.addons.ui.FlxUITooltip.FlxUITooltipStyle; +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.group.FlxGroup; import flixel.math.FlxMath; import flixel.math.FlxPoint; +import flixel.math.FlxRect; import flixel.system.FlxSound; import flixel.text.FlxText; -import flixel.ui.FlxButton; -import flixel.ui.FlxSpriteButton; +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.events.Event; -import openfl.events.IOErrorEvent; -import openfl.events.IOErrorEvent; -import openfl.events.IOErrorEvent; -import openfl.media.Sound; -import openfl.net.FileReference; -import openfl.utils.ByteArray; +import openfl.display.BlendMode; +import openfl.display.StageQuality; +import openfl.filters.ShaderFilter; + +#if windows +import Discord.DiscordClient; +#end +#if windows +import Sys; +import sys.FileSystem; +#end using StringTools; -class ChartingState extends MusicBeatState +class PlayState extends MusicBeatState { - var _file:FileReference; + public static var instance:PlayState = null; - var UI_box:FlxUITabMenu; + 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; + public static var weekSong:Int = 0; + public static var shits:Int = 0; + public static var bads:Int = 0; + public static var goods:Int = 0; + public static var sicks:Int = 0; - /** - * Array of notes showing when each section STARTS in STEPS - * Usually rounded up?? - */ - var curSection:Int = 0; + public static var songPosBG:FlxSprite; + public static var songPosBar:FlxBar; - public static var lastSection:Int = 0; + public static var rep:Replay; + public static var loadRep:Bool = false; - var bpmTxt:FlxText; + public static var noteBools:Array = [false, false, false, false]; - var strumLine:FlxSprite; - var curSong:String = 'Dadbattle'; - var amountSteps:Int = 0; - var bullshitUI:FlxGroup; - var writingNotesText:FlxText; - var highlight:FlxSprite; + var halloweenLevel:Bool = false; - var GRID_SIZE:Int = 40; + var songLength:Float = 0; + var kadeEngineWatermark:FlxText; + + #if windows + // Discord RPC variables + var storyDifficultyText:String = ""; + var iconRPC:String = ""; + var detailsText:String = ""; + var detailsPausedText:String = ""; + #end - var dummyArrow:FlxSprite; + private var vocals:FlxSound; - var curRenderedNotes:FlxTypedGroup; - var curRenderedSustains:FlxTypedGroup; + public static var dad:Character; + public static var gf:Character; + public static var boyfriend:Boyfriend; - var gridBG:FlxSprite; + public var notes:FlxTypedGroup; + private var unspawnNotes:Array = []; - var _song:SwagSong; + public var strumLine:FlxSprite; + private var curSection:Int = 0; - var typingShit:FlxInputText; - /* - * WILL BE THE CURRENT / LAST PLACED NOTE - **/ - var curSelectedNote:Array; + private var camFollow:FlxObject; - var tempBpm:Int = 0; - var gridBlackLine:FlxSprite; - var vocals:FlxSound; + private static var prevCamFollow:FlxObject; - var player2:Character = new Character(0,0, "dad"); - var player1:Boyfriend = new Boyfriend(0,0, "bf"); + public static var strumLineNotes:FlxTypedGroup = null; + public static var playerStrums:FlxTypedGroup = null; - var leftIcon:HealthIcon; - var rightIcon:HealthIcon; + private var camZooming:Bool = false; + private var curSong:String = ""; - private var lastNote:Note; + private var gfSpeed:Int = 1; + private var health:Float = 1; + private var combo:Int = 0; + public static var misses:Int = 0; + private var accuracy:Float = 0.00; + private var accuracyDefault:Float = 0.00; + private var totalNotesHit:Float = 0; + private var totalNotesHitDefault:Float = 0; + private var totalPlayed:Int = 0; + private var ss:Bool = false; - override function create() + + private var healthBarBG:FlxSprite; + private var healthBar:FlxBar; + private var songPositionBar:Float = 0; + + private var generatedMusic:Bool = false; + private var startingSong:Bool = false; + + private var iconP1:HealthIcon; + private var iconP2:HealthIcon; + public var camHUD:FlxCamera; + private var camGame:FlxCamera; + + public static var offsetTesting:Bool = false; + + var notesHitArray:Array = []; + var currentFrames:Int = 0; + + var dialogue:Array = ['dad:blah blah blah', 'bf: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 songName:FlxText; + var upperBoppers:FlxSprite; + var bottomBoppers:FlxSprite; + var santa:FlxSprite; + + var fc:Bool = true; + + var bgGirls:BackgroundGirls; + var wiggleShit:WiggleEffect = new WiggleEffect(); + + var talking:Bool = true; + var songScore:Int = 0; + var songScoreDef:Int = 0; + var scoreTxt:FlxText; + var replayTxt:FlxText; + + public static var campaignScore:Int = 0; + + var defaultCamZoom:Float = 1.05; + + public static var daPixelZoom:Float = 6; + + public static var theFunne:Bool = true; + var funneEffect:FlxSprite; + var inCutscene:Bool = false; + public static var repPresses:Int = 0; + public static var repReleases:Int = 0; + + public static var timeCurrently:Float = 0; + public static var timeCurrentlyR:Float = 0; + + // Will fire once to prevent debug spam messages and broken animations + private var triggeredAlready:Bool = false; + + // Will decide if she's even allowed to headbang at all depending on the song + private var allowedToHeadbang:Bool = false; + // Per song additive offset + public static var songOffset:Float = 0; + + private var executeModchart = false; + + // API stuff + + public function addObject(object:FlxBasic) { add(object); } + public function removeObject(object:FlxBasic) { remove(object); } + + + override public function create() { - curSection = lastSection; + instance = this; + - if (PlayState.SONG != null) - _song = PlayState.SONG; - else + if (FlxG.sound.music != null) + FlxG.sound.music.stop(); + + sicks = 0; + bads = 0; + shits = 0; + goods = 0; + + misses = 0; + + repPresses = 0; + repReleases = 0; + + #if windows + executeModchart = FileSystem.exists(Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart")); + #end + #if !cpp + executeModchart = false; // FORCE disable for non cpp targets + #end + + trace('Mod chart: ' + executeModchart + " - " + Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart")); + + #if windows + // Making difficulty text for Discord Rich Presence. + switch (storyDifficulty) { - _song = { - song: 'Test', - notes: [], - bpm: 150, - needsVoices: true, - player1: 'bf', - player2: 'dad', - gfVersion: 'gf', - noteStyle: 'normal', - stage: 'stage', - speed: 1, - validScore: false - }; + case 0: + storyDifficultyText = "Easy"; + case 1: + storyDifficultyText = "Normal"; + case 2: + storyDifficultyText = "Hard"; } - gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * 16); - add(gridBG); + iconRPC = SONG.player2; - gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK); - add(gridBlackLine); + // 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'; + } - curRenderedNotes = new FlxTypedGroup(); - curRenderedSustains = new FlxTypedGroup(); + // 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"; + } - FlxG.mouse.visible = true; - FlxG.save.bind('funkin', 'ninjamuffin99'); + // String for when the game is paused + detailsPausedText = "Paused - " + detailsText; - tempBpm = _song.bpm; + // Updating Discord Rich Presence. + DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); + #end - addSection(); - // sections = _song.notes; + // var gameCam:FlxCamera = FlxG.camera; + camGame = new FlxCamera(); + camHUD = new FlxCamera(); + camHUD.bgColor.alpha = 0; - updateGrid(); + FlxG.cameras.reset(camGame); + FlxG.cameras.add(camHUD); - loadSong(_song.song); - Conductor.changeBPM(_song.bpm); - Conductor.mapBPMChanges(_song); + FlxCamera.defaultCameras = [camGame]; - leftIcon = new HealthIcon(_song.player1); - rightIcon = new HealthIcon(_song.player2); - leftIcon.scrollFactor.set(1, 1); - rightIcon.scrollFactor.set(1, 1); + persistentUpdate = true; + persistentDraw = true; - leftIcon.setGraphicSize(0, 45); - rightIcon.setGraphicSize(0, 45); + if (SONG == null) + SONG = Song.loadFromJson('tutorial'); - add(leftIcon); - add(rightIcon); + Conductor.mapBPMChanges(SONG); + Conductor.changeBPM(SONG.bpm); - leftIcon.setPosition(0, -100); - rightIcon.setPosition(gridBG.width / 2, -100); + trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + Conductor.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: ' + Conductor.timeScale); + + 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')); + } - bpmTxt = new FlxText(1000, 50, 0, "", 16); - bpmTxt.scrollFactor.set(); - add(bpmTxt); + switch(SONG.stage) + { + case 'halloween': + { + curStage = 'spooky'; + halloweenLevel = true; - strumLine = new FlxSprite(0, 50).makeGraphic(Std.int(FlxG.width / 2), 4); - add(strumLine); + var hallowTex = Paths.getSparrowAtlas('halloween_bg','week2'); - dummyArrow = new FlxSprite().makeGraphic(GRID_SIZE, GRID_SIZE); - add(dummyArrow); + 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); - var tabs = [ - {name: "Song", label: 'Song'}, - {name: "Section", label: 'Section'}, - {name: "Note", label: 'Note Data'}, - {name: "Assets", label: 'Assets'} - ]; + isHalloween = true; + } + case 'philly': + { + curStage = 'philly'; - UI_box = new FlxUITabMenu(null, tabs, true); + var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky', 'week3')); + bg.scrollFactor.set(0.1, 0.1); + add(bg); - UI_box.resize(300, 400); - UI_box.x = FlxG.width / 2; - UI_box.y = 20; - add(UI_box); + var city:FlxSprite = new FlxSprite(-10).loadGraphic(Paths.image('philly/city', 'week3')); + city.scrollFactor.set(0.3, 0.3); + city.setGraphicSize(Std.int(city.width * 0.85)); + city.updateHitbox(); + add(city); - addSongUI(); - addSectionUI(); - addNoteUI(); + phillyCityLights = new FlxTypedGroup(); + if(FlxG.save.data.distractions){ + add(phillyCityLights); + } - add(curRenderedNotes); - add(curRenderedSustains); + for (i in 0...5) + { + var light:FlxSprite = new FlxSprite(city.x).loadGraphic(Paths.image('philly/win' + i, 'week3')); + 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','week3')); + add(streetBehind); + + phillyTrain = new FlxSprite(2000, 360).loadGraphic(Paths.image('philly/train','week3')); + if(FlxG.save.data.distractions){ + add(phillyTrain); + } + + trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes','week3')); + 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','week3')); + add(street); + } + case 'limo': + { + curStage = 'limo'; + defaultCamZoom = 0.90; + + var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic(Paths.image('limo/limoSunset','week4')); + skyBG.scrollFactor.set(0.1, 0.1); + add(skyBG); + + var bgLimo:FlxSprite = new FlxSprite(-200, 480); + bgLimo.frames = Paths.getSparrowAtlas('limo/bgLimo','week4'); + bgLimo.animation.addByPrefix('drive', "background limo pink", 24); + bgLimo.animation.play('drive'); + bgLimo.scrollFactor.set(0.4, 0.4); + add(bgLimo); + if(FlxG.save.data.distractions){ + 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','week4')); + 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','week4'); + + 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','week4')); + // add(limo); + } + case 'mall': + { + curStage = 'mall'; + + defaultCamZoom = 0.80; + + var bg:FlxSprite = new FlxSprite(-1000, -500).loadGraphic(Paths.image('christmas/bgWalls','week5')); + 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','week5'); + 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(); + if(FlxG.save.data.distractions){ + add(upperBoppers); + } + + + var bgEscalator:FlxSprite = new FlxSprite(-1100, -600).loadGraphic(Paths.image('christmas/bgEscalator','week5')); + 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','week5')); + tree.antialiasing = true; + tree.scrollFactor.set(0.40, 0.40); + add(tree); + + bottomBoppers = new FlxSprite(-300, 140); + bottomBoppers.frames = Paths.getSparrowAtlas('christmas/bottomBop','week5'); + 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(); + if(FlxG.save.data.distractions){ + add(bottomBoppers); + } + + + var fgSnow:FlxSprite = new FlxSprite(-600, 700).loadGraphic(Paths.image('christmas/fgSnow','week5')); + fgSnow.active = false; + fgSnow.antialiasing = true; + add(fgSnow); + + santa = new FlxSprite(-840, 150); + santa.frames = Paths.getSparrowAtlas('christmas/santa','week5'); + santa.animation.addByPrefix('idle', 'santa idle in fear', 24, false); + santa.antialiasing = true; + if(FlxG.save.data.distractions){ + add(santa); + } + } + case 'mallEvil': + { + curStage = 'mallEvil'; + var bg:FlxSprite = new FlxSprite(-400, -500).loadGraphic(Paths.image('christmas/evilBG','week5')); + 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','week5')); + evilTree.antialiasing = true; + evilTree.scrollFactor.set(0.2, 0.2); + add(evilTree); + + var evilSnow:FlxSprite = new FlxSprite(-200, 700).loadGraphic(Paths.image("christmas/evilSnow",'week5')); + evilSnow.antialiasing = true; + add(evilSnow); + } + case 'school': + { + curStage = 'school'; + + // defaultCamZoom = 0.9; + + var bgSky = new FlxSprite().loadGraphic(Paths.image('weeb/weebSky','week6')); + bgSky.scrollFactor.set(0.1, 0.1); + add(bgSky); + + var repositionShit = -200; + + var bgSchool:FlxSprite = new FlxSprite(repositionShit, 0).loadGraphic(Paths.image('weeb/weebSchool','week6')); + bgSchool.scrollFactor.set(0.6, 0.90); + add(bgSchool); + + var bgStreet:FlxSprite = new FlxSprite(repositionShit).loadGraphic(Paths.image('weeb/weebStreet','week6')); + bgStreet.scrollFactor.set(0.95, 0.95); + add(bgStreet); + + var fgTrees:FlxSprite = new FlxSprite(repositionShit + 170, 130).loadGraphic(Paths.image('weeb/weebTreesBack','week6')); + fgTrees.scrollFactor.set(0.9, 0.9); + add(fgTrees); + + var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800); + var treetex = Paths.getPackerAtlas('weeb/weebTrees','week6'); + 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','week6'); + 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') + { + if(FlxG.save.data.distractions){ + bgGirls.getScared(); + } + } + + bgGirls.setGraphicSize(Std.int(bgGirls.width * daPixelZoom)); + bgGirls.updateHitbox(); + if(FlxG.save.data.distractions){ + add(bgGirls); + } + } + case 'schoolEvil': + { + 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','week6'); + 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); + */ + } + case 'stage': + { + 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); + } + 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 (SONG.gfVersion) + { + case 'gf-car': + gfVersion = 'gf-car'; + case 'gf-christmas': + gfVersion = 'gf-christmas'; + case 'gf-pixel': + gfVersion = 'gf-pixel'; + case 'gf': + gfVersion = 'gf'; + default: + gfVersion = 'gf'; + } + + 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; + if(FlxG.save.data.distractions){ + 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': + if(FlxG.save.data.distractions){ + // 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(); + + if (FlxG.save.data.downscroll) + strumLine.y = FlxG.height - 165; + + 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 * (30 / (cast (Lib.current.getChildAt(0), Main)).getFPS())); + // 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; + + if (FlxG.save.data.songPosition) // I dont wanna talk about this code :( + { + songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar')); + if (FlxG.save.data.downscroll) + songPosBG.y = FlxG.height * 0.9 + 45; + songPosBG.screenCenter(X); + songPosBG.scrollFactor.set(); + add(songPosBG); + + songPosBar = new FlxBar(songPosBG.x + 4, songPosBG.y + 4, LEFT_TO_RIGHT, Std.int(songPosBG.width - 8), Std.int(songPosBG.height - 8), this, + 'songPositionBar', 0, 90000); + songPosBar.scrollFactor.set(); + songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); + add(songPosBar); + + var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - 20,songPosBG.y,0,SONG.song, 16); + if (FlxG.save.data.downscroll) + songName.y -= 3; + songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + songName.scrollFactor.set(); + add(songName); + songName.cameras = [camHUD]; + } + + healthBarBG = new FlxSprite(0, FlxG.height * 0.9).loadGraphic(Paths.image('healthBar')); + if (FlxG.save.data.downscroll) + healthBarBG.y = 50; + 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); + + // Add Kade Engine watermark + kadeEngineWatermark = new FlxText(4,healthBarBG.y + 50,0,SONG.song + " " + (storyDifficulty == 2 ? "Hard" : storyDifficulty == 1 ? "Normal" : "Easy") + (Main.watermarks ? " - KE " + MainMenuState.kadeEngineVer : ""), 16); + kadeEngineWatermark.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + kadeEngineWatermark.scrollFactor.set(); + add(kadeEngineWatermark); + + if (FlxG.save.data.downscroll) + kadeEngineWatermark.y = FlxG.height * 0.9 + 45; + + scoreTxt = new FlxText(FlxG.width / 2 - 235, healthBarBG.y + 50, 0, "", 20); + if (!FlxG.save.data.accuracyDisplay) + scoreTxt.x = healthBarBG.x + healthBarBG.width / 2; + scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + if (offsetTesting) + scoreTxt.x += 300; + add(scoreTxt); + + replayTxt = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (FlxG.save.data.downscroll ? 100 : -100), 0, "REPLAY", 20); + replayTxt.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + replayTxt.scrollFactor.set(); + if (loadRep) + { + add(replayTxt); + } + + 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 (FlxG.save.data.songPosition) + { + songPosBG.cameras = [camHUD]; + songPosBar.cameras = [camHUD]; + } + kadeEngineWatermark.cameras = [camHUD]; + if (loadRep) + replayTxt.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(); + } + } + + if (!loadRep) + rep = new Replay("na"); super.create(); } - function addSongUI():Void + function schoolIntro(?dialogueBox:DialogueBox):Void { - var UI_songTitle = new FlxUIInputText(10, 10, 70, _song.song, 8); - typingShit = UI_songTitle; + var black:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); + black.scrollFactor.set(); + add(black); - var check_voices = new FlxUICheckBox(10, 25, null, null, "Has voice track", 100); - check_voices.checked = _song.needsVoices; - // _song.needsVoices = check_voices.checked; - check_voices.callback = function() + 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') { - _song.needsVoices = check_voices.checked; - trace('CHECKED!'); - }; + remove(black); - var check_mute_inst = new FlxUICheckBox(10, 200, null, null, "Mute Instrumental (in editor)", 100); - check_mute_inst.checked = false; - check_mute_inst.callback = function() - { - var vol:Float = 1; - - if (check_mute_inst.checked) - vol = 0; - - FlxG.sound.music.volume = vol; - }; - - var saveButton:FlxButton = new FlxButton(110, 8, "Save", function() - { - saveLevel(); - }); - - var reloadSong:FlxButton = new FlxButton(saveButton.x + saveButton.width + 10, saveButton.y, "Reload Audio", function() - { - loadSong(_song.song); - }); - - var reloadSongJson:FlxButton = new FlxButton(reloadSong.x, saveButton.y + 30, "Reload JSON", function() - { - loadJson(_song.song.toLowerCase()); - }); - - - var restart = new FlxButton(10,140,"Reset Chart", function() - { - for (ii in 0..._song.notes.length) - { - for (i in 0..._song.notes[ii].sectionNotes.length) - { - _song.notes[ii].sectionNotes = []; - } - } - resetSection(true); - }); - - var loadAutosaveBtn:FlxButton = new FlxButton(reloadSongJson.x, reloadSongJson.y + 30, 'load autosave', loadAutosave); - - var stepperSpeed:FlxUINumericStepper = new FlxUINumericStepper(10, 80, 0.1, 1, 0.1, 10, 1); - stepperSpeed.value = _song.speed; - stepperSpeed.name = 'song_speed'; - - var stepperSpeedLabel = new FlxText(74,80,'Scroll Speed'); - - var stepperBPM:FlxUINumericStepper = new FlxUINumericStepper(10, 65, 0.1, 1, 1.0, 5000.0, 1); - stepperBPM.value = Conductor.bpm; - stepperBPM.name = 'song_bpm'; - - var stepperBPMLabel = new FlxText(74,65,'BPM'); - - var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); - var gfVersions:Array = CoolUtil.coolTextFile(Paths.txt('gfVersionList')); - var stages:Array = CoolUtil.coolTextFile(Paths.txt('stageList')); - var noteStyles:Array = CoolUtil.coolTextFile(Paths.txt('noteStyleList')); - - var player1DropDown = new FlxUIDropDownMenu(10, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) - { - _song.player1 = characters[Std.parseInt(character)]; - }); - player1DropDown.selectedLabel = _song.player1; - - var player1Label = new FlxText(10,80,64,'Player 1'); - - var player2DropDown = new FlxUIDropDownMenu(140, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) - { - _song.player2 = characters[Std.parseInt(character)]; - }); - player2DropDown.selectedLabel = _song.player2; - - var player2Label = new FlxText(140,80,64,'Player 2'); - - var gfVersionDropDown = new FlxUIDropDownMenu(10, 200, FlxUIDropDownMenu.makeStrIdLabelArray(gfVersions, true), function(gfVersion:String) + if (SONG.song.toLowerCase() == 'thorns') { - _song.gfVersion = gfVersions[Std.parseInt(gfVersion)]; - }); - gfVersionDropDown.selectedLabel = _song.gfVersion; - - var gfVersionLabel = new FlxText(10,180,64,'Girlfriend'); - - var stageDropDown = new FlxUIDropDownMenu(140, 200, FlxUIDropDownMenu.makeStrIdLabelArray(stages, true), function(stage:String) - { - _song.stage = stages[Std.parseInt(stage)]; - }); - stageDropDown.selectedLabel = _song.stage; - - var stageLabel = new FlxText(140,180,64,'Stage'); - - var noteStyleDropDown = new FlxUIDropDownMenu(10, 300, FlxUIDropDownMenu.makeStrIdLabelArray(noteStyles, true), function(noteStyle:String) - { - _song.noteStyle = noteStyles[Std.parseInt(noteStyle)]; - }); - noteStyleDropDown.selectedLabel = _song.noteStyle; - - var noteStyleLabel = new FlxText(10,280,64,'Note Skin'); - - var tab_group_song = new FlxUI(null, UI_box); - tab_group_song.name = "Song"; - tab_group_song.add(UI_songTitle); - tab_group_song.add(restart); - tab_group_song.add(check_voices); - tab_group_song.add(check_mute_inst); - tab_group_song.add(saveButton); - tab_group_song.add(reloadSong); - tab_group_song.add(reloadSongJson); - tab_group_song.add(loadAutosaveBtn); - tab_group_song.add(stepperBPM); - tab_group_song.add(stepperBPMLabel); - tab_group_song.add(stepperSpeed); - tab_group_song.add(stepperSpeedLabel); - - var tab_group_assets = new FlxUI(null, UI_box); - tab_group_assets.name = "Assets"; - tab_group_assets.add(noteStyleDropDown); - tab_group_assets.add(noteStyleLabel); - tab_group_assets.add(gfVersionDropDown); - tab_group_assets.add(gfVersionLabel); - tab_group_assets.add(stageDropDown); - tab_group_assets.add(stageLabel); - tab_group_assets.add(player1DropDown); - tab_group_assets.add(player2DropDown); - tab_group_assets.add(player1Label); - tab_group_assets.add(player2Label); - - UI_box.addGroup(tab_group_song); - UI_box.addGroup(tab_group_assets); - UI_box.scrollFactor.set(); - - FlxG.camera.follow(strumLine); - } - - var stepperLength:FlxUINumericStepper; - var check_mustHitSection:FlxUICheckBox; - var check_changeBPM:FlxUICheckBox; - var stepperSectionBPM:FlxUINumericStepper; - var check_altAnim:FlxUICheckBox; - - function addSectionUI():Void - { - var tab_group_section = new FlxUI(null, UI_box); - tab_group_section.name = 'Section'; - - stepperLength = new FlxUINumericStepper(10, 10, 4, 0, 0, 999, 0); - stepperLength.value = _song.notes[curSection].lengthInSteps; - stepperLength.name = "section_length"; - - stepperSectionBPM = new FlxUINumericStepper(10, 80, 1, Conductor.bpm, 0, 999, 0); - stepperSectionBPM.value = Conductor.bpm; - stepperSectionBPM.name = 'section_bpm'; - - var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 130, 1, 1, -999, 999, 0); - - var copyButton:FlxButton = new FlxButton(10, 130, "Copy last section", function() - { - copySection(Std.int(stepperCopy.value)); - }); - - var clearSectionButton:FlxButton = new FlxButton(10, 150, "Clear", clearSection); - - var swapSection:FlxButton = new FlxButton(10, 170, "Swap section", function() - { - for (i in 0..._song.notes[curSection].sectionNotes.length) - { - var note = _song.notes[curSection].sectionNotes[i]; - note[1] = (note[1] + 4) % 8; - _song.notes[curSection].sectionNotes[i] = note; - updateGrid(); - } - }); - - check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Must hit section", 100); - check_mustHitSection.name = 'check_mustHit'; - check_mustHitSection.checked = true; - // _song.needsVoices = check_mustHit.checked; - - check_altAnim = new FlxUICheckBox(10, 400, null, null, "Alt Animation", 100); - check_altAnim.name = 'check_altAnim'; - - check_changeBPM = new FlxUICheckBox(10, 60, null, null, 'Change BPM', 100); - check_changeBPM.name = 'check_changeBPM'; - - tab_group_section.add(stepperLength); - tab_group_section.add(stepperSectionBPM); - tab_group_section.add(stepperCopy); - tab_group_section.add(check_mustHitSection); - tab_group_section.add(check_altAnim); - tab_group_section.add(check_changeBPM); - tab_group_section.add(copyButton); - tab_group_section.add(clearSectionButton); - tab_group_section.add(swapSection); - - UI_box.addGroup(tab_group_section); - } - - var stepperSusLength:FlxUINumericStepper; - - var tab_group_note:FlxUI; - - function addNoteUI():Void - { - tab_group_note = new FlxUI(null, UI_box); - tab_group_note.name = 'Note'; - - writingNotesText = new FlxUIText(20,100, 0, ""); - writingNotesText.setFormat("Arial",20,FlxColor.WHITE,FlxTextAlign.LEFT,FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - - stepperSusLength = new FlxUINumericStepper(10, 10, Conductor.stepCrochet / 2, 0, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps * 4); - stepperSusLength.value = 0; - stepperSusLength.name = 'note_susLength'; - - var stepperSusLengthLabel = new FlxText(74,10,'Note Sustain Length'); - - var applyLength:FlxButton = new FlxButton(10, 100, 'Apply Data'); - - tab_group_note.add(writingNotesText); - tab_group_note.add(stepperSusLength); - tab_group_note.add(stepperSusLengthLabel); - tab_group_note.add(applyLength); - - UI_box.addGroup(tab_group_note); - - /*player2 = new Character(0,gridBG.y, _song.player2); - player1 = new Boyfriend(player2.width * 0.2,gridBG.y + player2.height, _song.player1); - - player1.y = player1.y - player1.height; - - player2.setGraphicSize(Std.int(player2.width * 0.2)); - player1.setGraphicSize(Std.int(player1.width * 0.2)); - - UI_box.add(player1); - UI_box.add(player2);*/ - - } - - function loadSong(daSong:String):Void - { - if (FlxG.sound.music != null) - { - FlxG.sound.music.stop(); - // vocals.stop(); - } - - FlxG.sound.playMusic(Paths.inst(daSong), 0.6); - - // WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER - vocals = new FlxSound().loadEmbedded(Paths.voices(daSong)); - FlxG.sound.list.add(vocals); - - FlxG.sound.music.pause(); - vocals.pause(); - - FlxG.sound.music.onComplete = function() - { - vocals.pause(); - vocals.time = 0; - FlxG.sound.music.pause(); - FlxG.sound.music.time = 0; - changeSection(); - }; - } - - function generateUI():Void - { - while (bullshitUI.members.length > 0) - { - bullshitUI.remove(bullshitUI.members[0], true); - } - - // general shit - var title:FlxText = new FlxText(UI_box.x + 20, UI_box.y + 20, 0); - bullshitUI.add(title); - /* - var loopCheck = new FlxUICheckBox(UI_box.x + 10, UI_box.y + 50, null, null, "Loops", 100, ['loop check']); - loopCheck.checked = curNoteSelected.doesLoop; - tooltips.add(loopCheck, {title: 'Section looping', body: "Whether or not it's a simon says style section", style: tooltipType}); - bullshitUI.add(loopCheck); - - */ - } - - override function getEvent(id:String, sender:Dynamic, data:Dynamic, ?params:Array) - { - if (id == FlxUICheckBox.CLICK_EVENT) - { - var check:FlxUICheckBox = cast sender; - var label = check.getLabel().text; - switch (label) - { - case 'Must hit section': - _song.notes[curSection].mustHitSection = check.checked; - case 'Change BPM': - _song.notes[curSection].changeBPM = check.checked; - FlxG.log.add('changed bpm shit'); - case "Alt Animation": - _song.notes[curSection].altAnim = check.checked; - } - } - else if (id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper)) - { - var nums:FlxUINumericStepper = cast sender; - var wname = nums.name; - FlxG.log.add(wname); - if (wname == 'section_length') - { - if (nums.value <= 4) - nums.value = 4; - _song.notes[curSection].lengthInSteps = Std.int(nums.value); - updateGrid(); - } - else if (wname == 'song_speed') - { - if (nums.value <= 0) - nums.value = 0; - _song.speed = nums.value; - } - else if (wname == 'song_bpm') - { - if (nums.value <= 0) - nums.value = 1; - tempBpm = Std.int(nums.value); - Conductor.mapBPMChanges(_song); - Conductor.changeBPM(Std.int(nums.value)); - } - else if (wname == 'note_susLength') - { - if (curSelectedNote == null) - return; - - if (nums.value <= 0) - nums.value = 0; - curSelectedNote[2] = nums.value; - updateGrid(); - } - else if (wname == 'section_bpm') - { - if (nums.value <= 0.1) - nums.value = 0.1; - _song.notes[curSection].bpm = Std.int(nums.value); - updateGrid(); + add(red); } } - // FlxG.log.add(id + " WEED " + sender + " WEED " + data + " WEED " + params); - } - - var updatedSection:Bool = false; - - /* this function got owned LOL - function lengthBpmBullshit():Float + new FlxTimer().start(0.3, function(tmr:FlxTimer) { - if (_song.notes[curSection].changeBPM) - return _song.notes[curSection].lengthInSteps * (_song.notes[curSection].bpm / _song.bpm); + black.alpha -= 0.15; + + if (black.alpha > 0) + { + tmr.reset(0.3); + } else - return _song.notes[curSection].lengthInSteps; - }*/ - function sectionStartTime():Float - { - var daBPM:Int = _song.bpm; - var daPos:Float = 0; - for (i in 0...curSection) - { - if (_song.notes[i].changeBPM) { - daBPM = _song.notes[i].bpm; - } - daPos += 4 * (1000 * 60 / daBPM); - } - return daPos; - } - - var writingNotes:Bool = false; - - override function update(elapsed:Float) - { - updateHeads(); - - curStep = recalculateSteps(); - - if (FlxG.keys.justPressed.ALT && UI_box.selected_tab == 0) - { - writingNotes = !writingNotes; - } - - if (writingNotes) - writingNotesText.text = "WRITING NOTES"; - else - writingNotesText.text = ""; - - Conductor.songPosition = FlxG.sound.music.time; - _song.song = typingShit.text; - - var upP = controls.UP_P; - var rightP = controls.RIGHT_P; - var downP = controls.DOWN_P; - var leftP = controls.LEFT_P; - - var controlArray:Array = [leftP, downP, upP, rightP]; - - if ((upP || rightP || downP || leftP) && writingNotes) - { - for(i in 0...controlArray.length) - { - if (controlArray[i]) + if (dialogueBox != null) { - for (n in 0..._song.notes[curSection].sectionNotes.length) - { - var note = _song.notes[curSection].sectionNotes[n]; - if (note == null) - continue; - if (note[0] == Conductor.songPosition && note[1] % 4 == i) - { - trace('GAMING'); - _song.notes[curSection].sectionNotes.remove(note); - } - } - trace('adding note'); - _song.notes[curSection].sectionNotes.push([Conductor.songPosition, i, 0]); - updateGrid(); - } - } + inCutscene = true; - } - - strumLine.y = getYfromStrum((Conductor.songPosition - sectionStartTime()) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps)); - - - /*curRenderedNotes.forEach(function(note:Note) { - if (strumLine.overlaps(note) && strumLine.y == note.y) // yandere dev type shit - { - if (_song.notes[curSection].mustHitSection) + if (SONG.song.toLowerCase() == 'thorns') { - trace('must hit ' + Math.abs(note.noteData)); - if (note.noteData < 4) + add(senpaiEvil); + senpaiEvil.alpha = 0; + new FlxTimer().start(0.3, function(swagTimer:FlxTimer) { - switch (Math.abs(note.noteData)) + senpaiEvil.alpha += 0.15; + if (senpaiEvil.alpha < 1) { - case 2: - player1.playAnim('singUP', true); - case 3: - player1.playAnim('singRIGHT', true); - case 1: - player1.playAnim('singDOWN', true); - case 0: - player1.playAnim('singLEFT', true); + swagTimer.reset(); } - } - if (note.noteData >= 4) - { - switch (note.noteData) + else { - case 6: - player2.playAnim('singUP', true); - case 7: - player2.playAnim('singRIGHT', true); - case 5: - player2.playAnim('singDOWN', true); - case 4: - player2.playAnim('singLEFT', true); + 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 { - trace('hit ' + Math.abs(note.noteData)); - if (note.noteData < 4) + add(dialogueBox); + } + } + else + startCountdown(); + + remove(black); + } + }); + } + + var startTimer:FlxTimer; + var perfectMode:Bool = false; + + var luaWiggles:Array = []; + + #if windows + public static var luaModchart:ModchartState = null; + #end + + function startCountdown():Void + { + inCutscene = false; + + generateStaticArrows(0); + generateStaticArrows(1); + + + #if windows + if (executeModchart) + { + luaModchart = ModchartState.createModchartState(); + luaModchart.executeState('start',[PlayState.SONG.song]); + } + #end + + 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' + altSuffix), 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) { - switch (Math.abs(note.noteData)) + ready.destroy(); + } + }); + FlxG.sound.play(Paths.sound('intro2' + altSuffix), 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' + altSuffix), 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' + altSuffix), 0.6); + case 4: + } + + swagCounter += 1; + // generateSong('fresh'); + }, 5); + } + + var previousFrameTime:Int = 0; + var lastReportedPlayheadPosition:Int = 0; + var songTime:Float = 0; + + + var songStarted = false; + + function startSong():Void + { + startingSong = false; + songStarted = true; + 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(); + + // Song duration in a float, useful for the time left feature + songLength = FlxG.sound.music.length; + + if (FlxG.save.data.songPosition) + { + remove(songPosBG); + remove(songPosBar); + remove(songName); + + songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar')); + if (FlxG.save.data.downscroll) + songPosBG.y = FlxG.height * 0.9 + 45; + songPosBG.screenCenter(X); + songPosBG.scrollFactor.set(); + add(songPosBG); + + songPosBar = new FlxBar(songPosBG.x + 4, songPosBG.y + 4, LEFT_TO_RIGHT, Std.int(songPosBG.width - 8), Std.int(songPosBG.height - 8), this, + 'songPositionBar', 0, songLength - 1000); + songPosBar.numDivisions = 1000; + songPosBar.scrollFactor.set(); + songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); + add(songPosBar); + + var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - 20,songPosBG.y,0,SONG.song, 16); + if (FlxG.save.data.downscroll) + songName.y -= 3; + songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + songName.scrollFactor.set(); + add(songName); + + songPosBG.cameras = [camHUD]; + songPosBar.cameras = [camHUD]; + songName.cameras = [camHUD]; + } + + // Song check real quick + switch(curSong) + { + case 'Bopeebo' | 'Philly' | 'Blammed' | 'Cocoa' | 'Eggnog': allowedToHeadbang = true; + default: allowedToHeadbang = false; + } + + #if windows + // Updating Discord Rich Presence (with Time Left) + DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); + #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; + + // Per song offset check + #if windows + var songPath = 'assets/data/' + PlayState.SONG.song.toLowerCase() + '/'; + for(file in sys.FileSystem.readDirectory(songPath)) + { + var path = haxe.io.Path.join([songPath, file]); + if(!sys.FileSystem.isDirectory(path)) + { + if(path.endsWith('.offset')) + { + trace('Found offset file: ' + path); + songOffset = Std.parseFloat(file.substring(0, file.indexOf('.off'))); + break; + }else { + trace('Offset file not found. Creating one @: ' + songPath); + sys.io.File.saveContent(songPath + songOffset + '.offset', ''); + } + } + } + #end + 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] + FlxG.save.data.offset + songOffset; + if (daStrumTime < 0) + daStrumTime = 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 (SONG.noteStyle) + { + case 'pixel': + 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); + } + + case 'normal': + 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); + } + + 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 windows + DiscordClient.changePresence("PAUSED on " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "Acc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); + #end + 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 windows + if (startTimer.finished) + { + DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses, iconRPC, true, songLength - Conductor.songPosition); + } + else + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), iconRPC); + } + #end + } + + super.closeSubState(); + } + + + function resyncVocals():Void + { + vocals.pause(); + + FlxG.sound.music.play(); + Conductor.songPosition = FlxG.sound.music.time; + vocals.time = Conductor.songPosition; + vocals.play(); + + #if windows + DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); + #end + } + + private var paused:Bool = false; + var startedCountdown:Bool = false; + var canPause:Bool = true; + + public static var songRate = 1.5; + + override public function update(elapsed:Float) + { + #if !debug + perfectMode = false; + #end + + #if windows + if (executeModchart && luaModchart != null && songStarted) + { + luaModchart.setVar('songPos',Conductor.songPosition); + luaModchart.setVar('hudZoom', camHUD.zoom); + luaModchart.setVar('cameraZoom',FlxG.camera.zoom); + luaModchart.executeState('update', [elapsed]); + + for (i in luaWiggles) + { + trace('wiggle le gaming'); + i.update(elapsed); + } + + /*for (i in 0...strumLineNotes.length) { + var member = strumLineNotes.members[i]; + member.x = luaModchart.getVar("strum" + i + "X", "float"); + member.y = luaModchart.getVar("strum" + i + "Y", "float"); + member.angle = luaModchart.getVar("strum" + i + "Angle", "float"); + }*/ + + FlxG.camera.angle = luaModchart.getVar('cameraAngle', 'float'); + camHUD.angle = luaModchart.getVar('camHudAngle','float'); + + if (luaModchart.getVar("showOnlyStrums",'bool')) + { + healthBarBG.visible = false; + kadeEngineWatermark.visible = false; + healthBar.visible = false; + iconP1.visible = false; + iconP2.visible = false; + scoreTxt.visible = false; + } + else + { + healthBarBG.visible = true; + kadeEngineWatermark.visible = true; + healthBar.visible = true; + iconP1.visible = true; + iconP2.visible = true; + scoreTxt.visible = true; + } + + var p1 = luaModchart.getVar("strumLine1Visible",'bool'); + var p2 = luaModchart.getVar("strumLine2Visible",'bool'); + + for (i in 0...4) + { + strumLineNotes.members[i].visible = p1; + if (i <= playerStrums.length) + playerStrums.members[i].visible = p2; + } + } + + #end + + if (currentFrames == FlxG.save.data.fpsCap) + { + for(i in 0...notesHitArray.length) + { + var cock:Date = notesHitArray[i]; + if (cock != null) + if (cock.getTime() + 2000 < Date.now().getTime()) + notesHitArray.remove(cock); + } + nps = Math.floor(notesHitArray.length / 2); + currentFrames = 0; + } + else + currentFrames++; + + 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 = Ratings.CalculateRanking(songScore,songScoreDef,nps,accuracy); + 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 (FlxG.keys.justPressed.SEVEN) + { + #if windows + DiscordClient.changePresence("Chart Editor", null, null, true); + #end + FlxG.switchState(new ChartingState()); + #if windows + if (luaModchart != null) + { + luaModchart.die(); + luaModchart = null; + } + #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)); + #if windows + if (luaModchart != null) + { + luaModchart.die(); + luaModchart = null; + } + #end + } + + #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; + /*@:privateAccess + { + FlxG.sound.music._channel. + }*/ + songPositionBar = Conductor.songPosition; + + 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) + { + // Make sure Girlfriend cheers only for certain songs + if(allowedToHeadbang) + { + // Don't animate GF if something else is already animating her (eg. train passing) + if(gf.animation.curAnim.name == 'danceLeft' || gf.animation.curAnim.name == 'danceRight' || gf.animation.curAnim.name == 'idle') + { + // Per song treatment since some songs will only have the 'Hey' at certain times + switch(curSong) + { + case 'Philly': + { + // General duration of the song + if(curBeat < 250) { - case 2: - player2.playAnim('singUP', true); - case 3: - player2.playAnim('singRIGHT', true); - case 1: - player2.playAnim('singDOWN', true); - case 0: - player2.playAnim('singLEFT', true); + // Beats to skip or to stop GF from cheering + if(curBeat != 184 && curBeat != 216) + { + if(curBeat % 16 == 8) + { + // Just a garantee that it'll trigger just once + if(!triggeredAlready) + { + gf.playAnim('cheer'); + triggeredAlready = true; + } + }else triggeredAlready = false; + } } } - if (note.noteData >= 4) + case 'Bopeebo': { - switch (note.noteData) + // Where it starts || where it ends + if(curBeat > 5 && curBeat < 130) { - case 6: - player1.playAnim('singUP', true); - case 7: - player1.playAnim('singRIGHT', true); - case 5: - player1.playAnim('singDOWN', true); - case 4: - player1.playAnim('singLEFT', true); + if(curBeat % 8 == 7) + { + if(!triggeredAlready) + { + gf.playAnim('cheer'); + triggeredAlready = true; + } + }else triggeredAlready = false; + } + } + case 'Blammed': + { + if(curBeat > 30 && curBeat < 190) + { + if(curBeat < 90 || curBeat > 128) + { + if(curBeat % 4 == 2) + { + if(!triggeredAlready) + { + gf.playAnim('cheer'); + triggeredAlready = true; + } + }else triggeredAlready = false; + } + } + } + case 'Cocoa': + { + if(curBeat < 170) + { + if(curBeat < 65 || curBeat > 130 && curBeat < 145) + { + if(curBeat % 16 == 15) + { + if(!triggeredAlready) + { + gf.playAnim('cheer'); + triggeredAlready = true; + } + }else triggeredAlready = false; + } + } + } + case 'Eggnog': + { + if(curBeat > 10 && curBeat != 111 && curBeat < 220) + { + if(curBeat % 8 == 7) + { + if(!triggeredAlready) + { + gf.playAnim('cheer'); + triggeredAlready = true; + } + }else triggeredAlready = false; } } } + } } - });*/ + + #if windows + if (luaModchart != null) + luaModchart.setVar("mustHit",PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection); + #end - if (curBeat % 4 == 0 && curStep >= 16 * (curSection + 1)) - { - trace(curStep); - trace((_song.notes[curSection].lengthInSteps) * (curSection + 1)); - trace('DUMBSHIT'); - - if (_song.notes[curSection + 1] == null) + if (camFollow.x != dad.getMidpoint().x + 150 && !PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection) { - addSection(); + var offsetX = 0; + var offsetY = 0; + #if windows + if (luaModchart != null) + { + offsetX = luaModchart.getVar("followXOffset", "float"); + offsetY = luaModchart.getVar("followYOffset", "float"); + } + #end + camFollow.setPosition(dad.getMidpoint().x + 150 + offsetX, dad.getMidpoint().y - 100 + offsetY); + #if windows + if (luaModchart != null) + luaModchart.executeState('playerTwoTurn', []); + #end + // 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; } - changeSection(curSection + 1, false); + if (PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection && camFollow.x != boyfriend.getMidpoint().x - 100) + { + var offsetX = 0; + var offsetY = 0; + #if windows + if (luaModchart != null) + { + offsetX = luaModchart.getVar("followXOffset", "float"); + offsetY = luaModchart.getVar("followYOffset", "float"); + } + #end + camFollow.setPosition(boyfriend.getMidpoint().x - 100 + offsetX, boyfriend.getMidpoint().y - 100 + offsetY); + + #if windows + if (luaModchart != null) + luaModchart.executeState('playerOneTurn', []); + #end + + 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; + } + } } - FlxG.watch.addQuick('daBeat', curBeat); - FlxG.watch.addQuick('daStep', curStep); - - if (FlxG.mouse.justPressed) + if (camZooming) { - if (FlxG.mouse.overlaps(curRenderedNotes)) + 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 (loadRep) // rep debug { - curRenderedNotes.forEach(function(note:Note) - { - if (FlxG.mouse.overlaps(note)) + FlxG.watch.addQuick('rep rpesses',repPresses); + FlxG.watch.addQuick('rep releases',repReleases); + // FlxG.watch.addQuick('Queued',inputsQueued); + } + + 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()); + } + } + + 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)); + + #if windows + // Game Over doesn't get his own variable because it's only used here + DiscordClient.changePresence("GAME OVER -- " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy),"\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC); + #end + + // FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); + } + + if (unspawnNotes[0] != null) + { + if (unspawnNotes[0].strumTime - Conductor.songPosition < 3500) + { + 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) + { + + // instead of doing stupid y > FlxG.height + // we be men and actually calculate the time :) + if (daNote.tooLate) { - if (FlxG.keys.pressed.CONTROL) + daNote.active = false; + daNote.visible = false; + } + else + { + daNote.visible = true; + daNote.active = true; + } + + if (!daNote.modifiedByLua) + { + if (FlxG.save.data.downscroll) { - selectNote(note); + if (daNote.mustPress) + daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); + else + daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); + if(daNote.isSustainNote) + { + // Remember = minus makes notes go up, plus makes them go down + if(daNote.animation.curAnim.name.endsWith('end') && daNote.prevNote != null) + daNote.y += daNote.prevNote.height; + else + daNote.y += daNote.height / 2; + + if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= (strumLine.y + Note.swagWidth / 2)) + { + // Clip to strumline + var swagRect = new FlxRect(0, 0, daNote.frameWidth * 2, daNote.frameHeight * 2); + swagRect.height = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + Note.swagWidth / 2 - daNote.y) / daNote.scale.y; + swagRect.y = daNote.frameHeight - swagRect.height; + + daNote.clipRect = swagRect; + } + } + }else + { + if (daNote.mustPress) + daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); + else + daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); + if(daNote.isSustainNote) + { + daNote.y -= daNote.height / 2; + + if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y + daNote.offset.y * daNote.scale.y <= (strumLine.y + Note.swagWidth / 2)) + { + // Clip to strumline + var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y); + swagRect.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + Note.swagWidth / 2 - daNote.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 2: + dad.playAnim('singUP' + altAnim, true); + case 3: + dad.playAnim('singRIGHT' + altAnim, true); + case 1: + dad.playAnim('singDOWN' + altAnim, true); + case 0: + dad.playAnim('singLEFT' + altAnim, true); + } + + #if windows + if (luaModchart != null) + luaModchart.executeState('playerTwoSing', [Math.abs(daNote.noteData), Conductor.songPosition]); + #end + + dad.holdTimer = 0; + + if (SONG.needsVoices) + vocals.volume = 1; + + daNote.active = false; + + daNote.kill(); + notes.remove(daNote, true); + daNote.destroy(); + } + + if (daNote.mustPress && !daNote.modifiedByLua) + { + daNote.visible = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].visible; + daNote.x = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].x; + if (!daNote.isSustainNote) + daNote.angle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle; + daNote.alpha = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].alpha; + } + else if (!daNote.wasGoodHit && !daNote.modifiedByLua) + { + daNote.visible = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].visible; + daNote.x = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].x; + if (!daNote.isSustainNote) + daNote.angle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].angle; + daNote.alpha = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].alpha; + } + + + + if (daNote.isSustainNote) + daNote.x += daNote.width / 2 + 17; + + + //trace(daNote.y); + // WIP interpolation shit? Need to fix the pause issue + // daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed)); + + if ((daNote.mustPress && daNote.tooLate && !FlxG.save.data.downscroll || daNote.mustPress && daNote.tooLate && FlxG.save.data.downscroll) && daNote.mustPress) + { + if (daNote.isSustainNote && daNote.wasGoodHit) + { + daNote.kill(); + notes.remove(daNote, true); + daNote.destroy(); } else { - deleteNote(note); + health -= 0.075; + vocals.volume = 0; + if (theFunne) + noteMiss(daNote.noteData, daNote); } + + daNote.active = false; + daNote.visible = false; + + daNote.kill(); + notes.remove(daNote, true); + daNote.destroy(); } }); } - else + + + if (!inCutscene) + keyShit(); + + + #if debug + if (FlxG.keys.justPressed.ONE) + endSong(); + #end + } + + function endSong():Void + { + if (!loadRep) + rep.SaveReplay(); + + #if windows + if (luaModchart != null) + { + luaModchart.die(); + luaModchart = null; + } + #end + + canPause = false; + FlxG.sound.music.volume = 0; + vocals.volume = 0; + if (SONG.validScore) + { + #if !switch + Highscore.saveScore(SONG.song, Math.round(songScore), storyDifficulty); + #end + } + + if (offsetTesting) + { + FlxG.sound.playMusic(Paths.music('freakyMenu')); + offsetTesting = false; + LoadingState.loadAndSwitchState(new OptionsMenu()); + FlxG.save.data.offset = offsetTest; + } + else + { + if (isStoryMode) { - if (FlxG.mouse.x > gridBG.x - && FlxG.mouse.x < gridBG.x + gridBG.width - && FlxG.mouse.y > gridBG.y - && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps)) + campaignScore += Math.round(songScore); + + storyPlaylist.remove(storyPlaylist[0]); + + if (storyPlaylist.length <= 0) { - FlxG.log.add('added note'); - addNote(); - } - } - } + FlxG.sound.playMusic(Paths.music('freakyMenu')); - if (FlxG.mouse.x > gridBG.x - && FlxG.mouse.x < gridBG.x + gridBG.width - && FlxG.mouse.y > gridBG.y - && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps)) - { - dummyArrow.x = Math.floor(FlxG.mouse.x / GRID_SIZE) * GRID_SIZE; - if (FlxG.keys.pressed.SHIFT) - dummyArrow.y = FlxG.mouse.y; - else - dummyArrow.y = Math.floor(FlxG.mouse.y / GRID_SIZE) * GRID_SIZE; - } + transIn = FlxTransitionableState.defaultTransIn; + transOut = FlxTransitionableState.defaultTransOut; - if (FlxG.keys.justPressed.ENTER) - { - lastSection = curSection; + FlxG.switchState(new StoryMenuState()); - PlayState.SONG = _song; - FlxG.sound.music.stop(); - vocals.stop(); - LoadingState.loadAndSwitchState(new PlayState()); - } + #if windows + if (luaModchart != null) + { + luaModchart.die(); + luaModchart = null; + } + #end - if (FlxG.keys.justPressed.E) - { - changeNoteSustain(Conductor.stepCrochet); - } - if (FlxG.keys.justPressed.Q) - { - changeNoteSustain(-Conductor.stepCrochet); - } + // if () + StoryMenuState.weekUnlocked[Std.int(Math.min(storyWeek + 1, StoryMenuState.weekUnlocked.length - 1))] = true; - if (FlxG.keys.justPressed.TAB) - { - if (FlxG.keys.pressed.SHIFT) - { - UI_box.selected_tab -= 1; - if (UI_box.selected_tab < 0) - UI_box.selected_tab = 2; - } - else - { - UI_box.selected_tab += 1; - if (UI_box.selected_tab >= 3) - UI_box.selected_tab = 0; - } - } + if (SONG.validScore) + { + NGio.unlockMedal(60961); + Highscore.saveWeekScore(storyWeek, campaignScore, storyDifficulty); + } - if (!typingShit.hasFocus) - { - - if (FlxG.keys.pressed.CONTROL) - { - if (FlxG.keys.justPressed.Z && lastNote != null) - { - trace(curRenderedNotes.members.contains(lastNote) ? "delete note" : "add note"); - if (curRenderedNotes.members.contains(lastNote)) - deleteNote(lastNote); - else - addNote(lastNote); - } - } - - var shiftThing:Int = 1; - if (FlxG.keys.pressed.SHIFT) - shiftThing = 4; - if (!writingNotes) - { - if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.D) - changeSection(curSection + shiftThing); - if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.A) - changeSection(curSection - shiftThing); - } - if (FlxG.keys.justPressed.SPACE) - { - if (FlxG.sound.music.playing) - { - FlxG.sound.music.pause(); - vocals.pause(); + FlxG.save.data.weekUnlocked = StoryMenuState.weekUnlocked; + FlxG.save.flush(); } else { - vocals.play(); - FlxG.sound.music.play(); - } - } + var difficulty:String = ""; - if (FlxG.keys.justPressed.R) - { - if (FlxG.keys.pressed.SHIFT) - resetSection(true); - else - resetSection(); - } + if (storyDifficulty == 0) + difficulty = '-easy'; - if (FlxG.mouse.wheel != 0) - { - FlxG.sound.music.pause(); - vocals.pause(); + if (storyDifficulty == 2) + difficulty = '-hard'; - FlxG.sound.music.time -= (FlxG.mouse.wheel * Conductor.stepCrochet * 0.4); - vocals.time = FlxG.sound.music.time; - } + trace('LOADING NEXT SONG'); + trace(PlayState.storyPlaylist[0].toLowerCase() + difficulty); - if (!FlxG.keys.pressed.SHIFT) - { - if (FlxG.keys.pressed.W || FlxG.keys.pressed.S) - { - FlxG.sound.music.pause(); - vocals.pause(); - - var daTime:Float = 700 * FlxG.elapsed; - - if (FlxG.keys.pressed.W) + if (SONG.song.toLowerCase() == 'eggnog') { - FlxG.sound.music.time -= daTime; - } - else - FlxG.sound.music.time += daTime; + 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; - vocals.time = FlxG.sound.music.time; + 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 { - if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S) + trace('WENT BACK TO FREEPLAY??'); + FlxG.switchState(new FreeplayState()); + } + } + } + + + var endingSong:Bool = false; + + var hits:Array = []; + var offsetTest:Float = 0; + + var timeShown = 0; + var currentTimingShown:FlxText = null; + + private function popUpScore(daNote:Note):Void + { + var noteDiff:Float = Math.abs(Conductor.songPosition - daNote.strumTime); + var wife:Float = EtternaFunctions.wife3(noteDiff, Conductor.timeScale); + // 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; + coolText.y -= 350; + coolText.cameras = [camHUD]; + // + + var rating:FlxSprite = new FlxSprite(); + var score:Float = 350; + + if (FlxG.save.data.accuracyMod == 1) + totalNotesHit += wife; + + var daRating = daNote.rating; + + switch(daRating) + { + case 'shit': + score = -300; + combo = 0; + misses++; + health -= 0.2; + ss = false; + shits++; + if (FlxG.save.data.accuracyMod == 0) + totalNotesHit += 0.25; + case 'bad': + daRating = 'bad'; + score = 0; + health -= 0.06; + ss = false; + bads++; + if (FlxG.save.data.accuracyMod == 0) + totalNotesHit += 0.50; + case 'good': + daRating = 'good'; + score = 200; + ss = false; + goods++; + if (health < 2) + health += 0.04; + if (FlxG.save.data.accuracyMod == 0) + totalNotesHit += 0.75; + case 'sick': + if (health < 2) + health += 0.1; + if (FlxG.save.data.accuracyMod == 0) + totalNotesHit += 1; + sicks++; + } + + // trace('Wife accuracy loss: ' + wife + ' | Rating: ' + daRating + ' | Score: ' + score + ' | Weight: ' + (1 - wife)); + + if (daRating != 'shit' || daRating != 'bad') { - FlxG.sound.music.pause(); - vocals.pause(); - - var daTime:Float = Conductor.stepCrochet * 2; - - if (FlxG.keys.justPressed.W) - { - FlxG.sound.music.time -= daTime; - } - else - FlxG.sound.music.time += daTime; - - vocals.time = FlxG.sound.music.time; - } - } - } - - _song.bpm = tempBpm; - - /* if (FlxG.keys.justPressed.UP) - Conductor.changeBPM(Conductor.bpm + 1); - if (FlxG.keys.justPressed.DOWN) - Conductor.changeBPM(Conductor.bpm - 1); */ - - bpmTxt.text = bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 2)) - + " / " - + Std.string(FlxMath.roundDecimal(FlxG.sound.music.length / 1000, 2)) - + "\nSection: " - + curSection - + "\nCurStep: " - + curStep; - super.update(elapsed); - } - - function changeNoteSustain(value:Float):Void - { - if (curSelectedNote != null) - { - if (curSelectedNote[2] != null) + + + songScore += Math.round(score); + songScoreDef += Math.round(ConvertScore.convertScore(noteDiff)); + + /* 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')) { - curSelectedNote[2] += value; - curSelectedNote[2] = Math.max(curSelectedNote[2], 0); - } - } - - updateNoteUI(); - updateGrid(); - } - - override function beatHit() - { - trace('beat'); - - super.beatHit(); - if (!player2.animation.curAnim.name.startsWith("sing")) - { - player2.playAnim('idle'); - } - player1.dance(); - } - - function recalculateSteps():Int - { - var lastChange:BPMChangeEvent = { - stepTime: 0, - songTime: 0, - bpm: 0 - } - for (i in 0...Conductor.bpmChangeMap.length) - { - if (FlxG.sound.music.time > Conductor.bpmChangeMap[i].songTime) - lastChange = Conductor.bpmChangeMap[i]; - } - - curStep = lastChange.stepTime + Math.floor((FlxG.sound.music.time - lastChange.songTime) / Conductor.stepCrochet); - updateBeat(); - - return curStep; - } - - function resetSection(songBeginning:Bool = false):Void - { - updateGrid(); - - FlxG.sound.music.pause(); - vocals.pause(); - - // Basically old shit from changeSection??? - FlxG.sound.music.time = sectionStartTime(); - - if (songBeginning) - { - FlxG.sound.music.time = 0; - curSection = 0; - } - - vocals.time = FlxG.sound.music.time; - updateCurStep(); - - updateGrid(); - updateSectionUI(); - } - - function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void - { - trace('changing section' + sec); - - if (_song.notes[sec] != null) - { - trace('naw im not null'); - curSection = sec; - - updateGrid(); - - if (updateMusic) - { - FlxG.sound.music.pause(); - vocals.pause(); - - /*var daNum:Int = 0; - var daLength:Float = 0; - while (daNum <= sec) - { - daLength += lengthBpmBullshit(); - daNum++; - }*/ - - FlxG.sound.music.time = sectionStartTime(); - vocals.time = FlxG.sound.music.time; - updateCurStep(); - } - - updateGrid(); - updateSectionUI(); - } - else - trace('bro wtf I AM NULL'); - } - - function copySection(?sectionNum:Int = 1) - { - var daSec = FlxMath.maxInt(curSection, sectionNum); - - for (note in _song.notes[daSec - sectionNum].sectionNotes) - { - var strum = note[0] + Conductor.stepCrochet * (_song.notes[daSec].lengthInSteps * sectionNum); - - var copiedNote:Array = [strum, note[1], note[2]]; - _song.notes[daSec].sectionNotes.push(copiedNote); - } - - updateGrid(); - } - - function updateSectionUI():Void - { - var sec = _song.notes[curSection]; - - stepperLength.value = sec.lengthInSteps; - check_mustHitSection.checked = sec.mustHitSection; - check_altAnim.checked = sec.altAnim; - check_changeBPM.checked = sec.changeBPM; - stepperSectionBPM.value = sec.bpm; - } - - function updateHeads():Void - { - if (check_mustHitSection.checked) - { - leftIcon.animation.play(_song.player1); - rightIcon.animation.play(_song.player2); - } - else - { - leftIcon.animation.play(_song.player2); - rightIcon.animation.play(_song.player1); - } - } - - function updateNoteUI():Void - { - if (curSelectedNote != null) - stepperSusLength.value = curSelectedNote[2]; - } - - function updateGrid():Void - { - remove(gridBG); - gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * _song.notes[curSection].lengthInSteps); - add(gridBG); - - remove(gridBlackLine); - gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK); - add(gridBlackLine); - - while (curRenderedNotes.members.length > 0) - { - curRenderedNotes.remove(curRenderedNotes.members[0], true); - } - - while (curRenderedSustains.members.length > 0) - { - curRenderedSustains.remove(curRenderedSustains.members[0], true); - } - - var sectionInfo:Array = _song.notes[curSection].sectionNotes; - - if (_song.notes[curSection].changeBPM && _song.notes[curSection].bpm > 0) - { - Conductor.changeBPM(_song.notes[curSection].bpm); - FlxG.log.add('CHANGED BPM!'); - } - else - { - // get last bpm - var daBPM:Int = _song.bpm; - for (i in 0...curSection) - if (_song.notes[i].changeBPM) - daBPM = _song.notes[i].bpm; - Conductor.changeBPM(daBPM); - } - - /* // PORT BULLSHIT, INCASE THERE'S NO SUSTAIN DATA FOR A NOTE - for (sec in 0..._song.notes.length) - { - for (notesse in 0..._song.notes[sec].sectionNotes.length) - { - if (_song.notes[sec].sectionNotes[notesse][2] == null) - { - trace('SUS NULL'); - _song.notes[sec].sectionNotes[notesse][2] = 0; - } - } - } - */ - - for (i in sectionInfo) - { - var daNoteInfo = i[1]; - var daStrumTime = i[0]; - var daSus = i[2]; - - var note:Note = new Note(daStrumTime, daNoteInfo % 4); - note.sustainLength = daSus; - note.setGraphicSize(GRID_SIZE, GRID_SIZE); - note.updateHitbox(); - note.x = Math.floor(daNoteInfo * GRID_SIZE); - note.y = Math.floor(getYfromStrum((daStrumTime - sectionStartTime()) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps))); - - if (curSelectedNote != null) - if (curSelectedNote[0] == note.strumTime) - lastNote = note; - - curRenderedNotes.add(note); - - if (daSus > 0) - { - var sustainVis:FlxSprite = new FlxSprite(note.x + (GRID_SIZE / 2), - note.y + GRID_SIZE).makeGraphic(8, Math.floor(FlxMath.remapToRange(daSus, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps, 0, gridBG.height))); - curRenderedSustains.add(sustainVis); - } - } - } - - private function addSection(lengthInSteps:Int = 16):Void - { - var sec:SwagSection = { - lengthInSteps: lengthInSteps, - bpm: _song.bpm, - changeBPM: false, - mustHitSection: true, - sectionNotes: [], - typeOfSection: 0, - altAnim: false - }; - - _song.notes.push(sec); - } - - function selectNote(note:Note):Void - { - var swagNum:Int = 0; - - for (i in _song.notes[curSection].sectionNotes) - { - if (i.strumTime == note.strumTime && i.noteData % 4 == note.noteData) - { - curSelectedNote = _song.notes[curSection].sectionNotes[swagNum]; - } - - swagNum += 1; - } - - updateGrid(); - updateNoteUI(); - } - - - function deleteNote(note:Note):Void - { - lastNote = note; - for (i in _song.notes[curSection].sectionNotes) - { - if (i[0] == note.strumTime && i[1] % 4 == note.noteData) - { - _song.notes[curSection].sectionNotes.remove(i); - } + pixelShitPart1 = 'weeb/pixelUI/'; + pixelShitPart2 = '-pixel'; } - updateGrid(); - } - - function clearSection():Void - { - _song.notes[curSection].sectionNotes = []; - - updateGrid(); - } - - function clearSong():Void - { - for (daSection in 0..._song.notes.length) - { - _song.notes[daSection].sectionNotes = []; - } - - updateGrid(); - } - - private function addNote(?n:Note):Void - { - var noteStrum = getStrumTime(dummyArrow.y) + sectionStartTime(); - var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE); - var noteSus = 0; - - if (n != null) - _song.notes[curSection].sectionNotes.push([n.strumTime, n.noteData, n.sustainLength]); - else - _song.notes[curSection].sectionNotes.push([noteStrum, noteData, noteSus]); - - var thingy = _song.notes[curSection].sectionNotes[_song.notes[curSection].sectionNotes.length - 1]; - - curSelectedNote = thingy; - - updateGrid(); - updateNoteUI(); - - autosaveSong(); - } - - function getStrumTime(yPos:Float):Float - { - return FlxMath.remapToRange(yPos, gridBG.y, gridBG.y + gridBG.height, 0, 16 * Conductor.stepCrochet); - } - - function getYfromStrum(strumTime:Float):Float - { - return FlxMath.remapToRange(strumTime, 0, 16 * Conductor.stepCrochet, gridBG.y, gridBG.y + gridBG.height); - } - - /* - function calculateSectionLengths(?sec:SwagSection):Int - { - var daLength:Int = 0; - - for (i in _song.notes) + rating.loadGraphic(Paths.image(pixelShitPart1 + daRating + pixelShitPart2)); + rating.screenCenter(); + rating.y -= 50; + rating.x = coolText.x - 125; + + if (FlxG.save.data.changedHit) { - var swagLength = i.lengthInSteps; + rating.x = FlxG.save.data.changedHitX; + rating.y = FlxG.save.data.changedHitY; + } + rating.acceleration.y = 550; + rating.velocity.y -= FlxG.random.int(140, 175); + rating.velocity.x -= FlxG.random.int(0, 10); + + + var msTiming = HelperFunctions.truncateFloat(noteDiff, 3); - if (i.typeOfSection == Section.COPYCAT) - swagLength * 2; + if (currentTimingShown != null) + remove(currentTimingShown); - daLength += swagLength; + currentTimingShown = new FlxText(0,0,0,"0ms"); + timeShown = 0; + switch(daRating) + { + case 'shit' | 'bad': + currentTimingShown.color = FlxColor.RED; + case 'good': + currentTimingShown.color = FlxColor.GREEN; + case 'sick': + currentTimingShown.color = FlxColor.CYAN; + } + currentTimingShown.borderStyle = OUTLINE; + currentTimingShown.borderSize = 1; + currentTimingShown.borderColor = FlxColor.BLACK; + currentTimingShown.text = msTiming + "ms"; + currentTimingShown.size = 20; - if (sec != null && sec == i) - { - trace('swag loop??'); - break; - } + if (msTiming >= 0.03 && offsetTesting) + { + //Remove Outliers + hits.shift(); + hits.shift(); + hits.shift(); + hits.pop(); + hits.pop(); + hits.pop(); + hits.push(msTiming); + + var total = 0.0; + + for(i in hits) + total += i; + + + + offsetTest = HelperFunctions.truncateFloat(total / hits.length,2); } - return daLength; - }*/ - private var daSpacing:Float = 0.3; + if (currentTimingShown.alpha != 1) + currentTimingShown.alpha = 1; - function loadLevel():Void - { - trace(_song.notes); - } + add(currentTimingShown); + - function getNotes():Array - { - var noteData:Array = []; - for (i in _song.notes) - { - noteData.push(i.sectionNotes); + var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); + comboSpr.screenCenter(); + comboSpr.x = rating.x; + comboSpr.y = rating.y + 100; + comboSpr.acceleration.y = 600; + comboSpr.velocity.y -= 150; + + currentTimingShown.screenCenter(); + currentTimingShown.x = comboSpr.x + 100; + currentTimingShown.y = rating.y + 100; + currentTimingShown.acceleration.y = 600; + currentTimingShown.velocity.y -= 150; + + comboSpr.velocity.x += FlxG.random.int(1, 10); + currentTimingShown.velocity.x += comboSpr.velocity.x; + 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)); + } + + currentTimingShown.updateHitbox(); + comboSpr.updateHitbox(); + rating.updateHitbox(); + + currentTimingShown.cameras = [camHUD]; + comboSpr.cameras = [camHUD]; + rating.cameras = [camHUD]; + + var seperatedScore:Array = []; + + var comboSplit:Array = (combo + "").split(''); + + if (comboSplit.length == 2) + seperatedScore.push(0); // make sure theres a 0 in front or it looks weird lol! + + for(i in 0...comboSplit.length) + { + var str:String = comboSplit[i]; + seperatedScore.push(Std.parseInt(str)); + } + + 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 = rating.x + (43 * daLoop) - 50; + numScore.y = rating.y + 100; + numScore.cameras = [camHUD]; + + 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, + onUpdate: function(tween:FlxTween) + { + if (currentTimingShown != null) + currentTimingShown.alpha -= 0.02; + timeShown++; + } + }); + + FlxTween.tween(comboSpr, {alpha: 0}, 0.2, { + onComplete: function(tween:FlxTween) + { + coolText.destroy(); + comboSpr.destroy(); + if (currentTimingShown != null && timeShown >= 20) + { + remove(currentTimingShown); + currentTimingShown = null; + } + rating.destroy(); + }, + startDelay: Conductor.crochet * 0.001 + }); + + curSection += 1; + } } - return noteData; + public function NearlyEquals(value1:Float, value2:Float, unimportantDifference:Float = 10):Bool + { + return Math.abs(FlxMath.roundDecimal(value1, 1) - FlxMath.roundDecimal(value2, 1)) < unimportantDifference; + } + + var upHold:Bool = false; + var downHold:Bool = false; + var rightHold:Bool = false; + var leftHold:Bool = false; + + private function keyShit():Void // I've invested in emma stocks + { + // control arrays, order L D R U + var holdArray:Array = [controls.LEFT, controls.DOWN, controls.UP, controls.RIGHT]; + var pressArray:Array = [ + controls.LEFT_P, + controls.DOWN_P, + controls.UP_P, + controls.RIGHT_P + ]; + var releaseArray:Array = [ + controls.LEFT_R, + controls.DOWN_R, + controls.UP_R, + controls.RIGHT_R + ]; + + // HOLDS, check for sustain notes + if (holdArray.contains(true) && /*!boyfriend.stunned && */ generatedMusic) + { + notes.forEachAlive(function(daNote:Note) + { + if (daNote.isSustainNote && daNote.canBeHit && daNote.mustPress && holdArray[daNote.noteData]) + goodNoteHit(daNote); + }); + } + + // PRESSES, check for note hits + if (pressArray.contains(true) && /*!boyfriend.stunned && */ generatedMusic) + { + boyfriend.holdTimer = 0; + + var possibleNotes:Array = []; // notes that can be hit + var directionList:Array = []; // directions that can be hit + var dumbNotes:Array = []; // notes to kill later + + notes.forEachAlive(function(daNote:Note) + { + if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit) + { + if (directionList.contains(daNote.noteData)) + { + for (coolNote in possibleNotes) + { + if (coolNote.noteData == daNote.noteData && Math.abs(daNote.strumTime - coolNote.strumTime) < 10) + { // if it's the same note twice at < 10ms distance, just delete it + // EXCEPT u cant delete it in this loop cuz it fucks with the collection lol + dumbNotes.push(daNote); + break; + } + else if (coolNote.noteData == daNote.noteData && daNote.strumTime < coolNote.strumTime) + { // if daNote is earlier than existing note (coolNote), replace + possibleNotes.remove(coolNote); + possibleNotes.push(daNote); + break; + } + } + } + else + { + possibleNotes.push(daNote); + directionList.push(daNote.noteData); + } + } + }); + + for (note in dumbNotes) + { + FlxG.log.add("killing dumb ass note at " + note.strumTime); + note.kill(); + notes.remove(note, true); + note.destroy(); + } + + possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime)); + + var dontCheck = false; + + for (i in 0...pressArray.length) + { + if (pressArray[i] && !directionList.contains(i)) + dontCheck = true; + } + + if (perfectMode) + goodNoteHit(possibleNotes[0]); + else if (possibleNotes.length > 0 && !dontCheck) + { + if (!FlxG.save.data.ghost) + { + for (shit in 0...pressArray.length) + { // if a direction is hit that shouldn't be + if (pressArray[shit] && !directionList.contains(shit)) + noteMiss(shit, null); + } + } + for (coolNote in possibleNotes) + { + if (pressArray[coolNote.noteData]) + { + if (mashViolations != 0) + mashViolations--; + scoreTxt.color = FlxColor.WHITE; + goodNoteHit(coolNote); + } + } + } + else if (!FlxG.save.data.ghost) + { + for (shit in 0...pressArray.length) + if (pressArray[shit]) + noteMiss(shit, null); + } + + if (dontCheck && possibleNotes.length > 0 && FlxG.save.data.ghost) + { + if (mashViolations > 4) + { + trace('mash violations ' + mashViolations); + scoreTxt.color = FlxColor.RED; + noteMiss(0,null); + } + else + mashViolations++; + } + + } + + if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && !holdArray.contains(true)) + { + if (boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss')) + { + boyfriend.playAnim('idle'); + } + } + + playerStrums.forEach(function(spr:FlxSprite) + { + if (pressArray[spr.ID] && spr.animation.curAnim.name != 'confirm') + spr.animation.play('pressed'); + if (!holdArray[spr.ID]) + 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, daNote:Note):Void + { + if (!boyfriend.stunned) + { + health -= 0.04; + if (combo > 5 && gf.animOffsets.exists('sad')) + { + gf.playAnim('sad'); + } + combo = 0; + misses++; + + //var noteDiff:Float = Math.abs(daNote.strumTime - Conductor.songPosition); + //var wife:Float = EtternaFunctions.wife3(noteDiff, FlxG.save.data.etternaMode ? 1 : 1.7); + + if (FlxG.save.data.accuracyMod == 1) + totalNotesHit -= 1; + + 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'); + + 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); + } + + #if windows + if (luaModchart != null) + luaModchart.executeState('playerOneMiss', [direction, Conductor.songPosition]); + #end + + + updateAccuracy(); + } } - function loadJson(song:String):Void - { - PlayState.SONG = Song.loadFromJson(song.toLowerCase(), song.toLowerCase()); - LoadingState.loadAndSwitchState(new ChartingState()); - } + /*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 (upP) + noteMiss(2); + if (rightP) + noteMiss(3); + if (downP) + noteMiss(1); + updateAccuracy(); + } + */ + function updateAccuracy() + { + totalPlayed += 1; + accuracy = Math.max(0,totalNotesHit / totalPlayed * 100); + accuracyDefault = Math.max(0, totalNotesHitDefault / totalPlayed * 100); + } - function loadAutosave():Void - { - PlayState.SONG = Song.parseJSONshit(FlxG.save.data.autosave); - LoadingState.loadAndSwitchState(new ChartingState()); - } - function autosaveSong():Void + function getKeyPresses(note:Note):Int { - FlxG.save.data.autosave = Json.stringify({ - "song": _song + var possibleNotes:Array = []; // copypasted but you already know that + + notes.forEachAlive(function(daNote:Note) + { + if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate) + { + possibleNotes.push(daNote); + possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime)); + } }); - FlxG.save.flush(); + if (possibleNotes.length == 1) + return possibleNotes.length + 1; + return possibleNotes.length; } + + var mashing:Int = 0; + var mashViolations:Int = 0; - private function saveLevel() - { - var json = { - "song": _song - }; + var etternaModeScore:Int = 0; - var data:String = Json.stringify(json); - - if ((data != null) && (data.length > 0)) + function noteCheck(controlArray:Array, note:Note):Void // sorry lol { - _file = new FileReference(); - _file.addEventListener(Event.COMPLETE, onSaveComplete); - _file.addEventListener(Event.CANCEL, onSaveCancel); - _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file.save(data.trim(), _song.song.toLowerCase() + ".json"); + var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition); + + note.rating = Ratings.CalculateRating(noteDiff); + + if (loadRep) + { + if (controlArray[note.noteData]) + goodNoteHit(note, false); + else if (rep.replay.keyPresses.length > repPresses && !controlArray[note.noteData]) + { + if (NearlyEquals(note.strumTime,rep.replay.keyPresses[repPresses].time, 4)) + { + goodNoteHit(note, false); + } + } + } + else if (controlArray[note.noteData]) + { + + goodNoteHit(note, (mashing > getKeyPresses(note))); + + /*if (mashing > getKeyPresses(note) && mashViolations <= 2) + { + mashViolations++; + + goodNoteHit(note, (mashing > getKeyPresses(note))); + } + else if (mashViolations > 2) + { + // this is bad but fuck you + playerStrums.members[0].animation.play('static'); + playerStrums.members[1].animation.play('static'); + playerStrums.members[2].animation.play('static'); + playerStrums.members[3].animation.play('static'); + health -= 0.4; + trace('mash ' + mashing); + if (mashing != 0) + mashing = 0; + } + else + goodNoteHit(note, false);*/ + + } + } + + var nps:Int = 0; + + function goodNoteHit(note:Note, resetMashViolation = true):Void + { + + if (mashing != 0) + mashing = 0; + + var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition); + + note.rating = Ratings.CalculateRating(noteDiff); + + if (!note.isSustainNote) + notesHitArray.push(Date.now()); + + if (!resetMashViolation && mashViolations >= 1) + mashViolations--; + + if (mashViolations < 0) + mashViolations = 0; + + if (!note.wasGoodHit) + { + if (!note.isSustainNote) + { + popUpScore(note); + combo += 1; + } + else + totalNotesHit += 1; + + + switch (note.noteData) + { + case 2: + boyfriend.playAnim('singUP', true); + case 3: + boyfriend.playAnim('singRIGHT', true); + case 1: + boyfriend.playAnim('singDOWN', true); + case 0: + boyfriend.playAnim('singLEFT', true); + } + + #if windows + if (luaModchart != null) + luaModchart.executeState('playerOneSing', [note.noteData, Conductor.songPosition]); + #end + + + if (!loadRep) + playerStrums.forEach(function(spr:FlxSprite) + { + if (Math.abs(note.noteData) == spr.ID) + { + spr.animation.play('confirm', true); + } + }); + + note.wasGoodHit = true; + vocals.volume = 1; + + note.kill(); + notes.remove(note, true); + note.destroy(); + + updateAccuracy(); + } + } + + + var fastCarCanDrive:Bool = true; + + function resetFastCar():Void + { + if(FlxG.save.data.distractions){ + fastCar.x = -12600; + fastCar.y = FlxG.random.int(140, 250); + fastCar.velocity.x = 0; + fastCarCanDrive = true; } } - function onSaveComplete(_):Void + function fastCarDrive() { - _file.removeEventListener(Event.COMPLETE, onSaveComplete); - _file.removeEventListener(Event.CANCEL, onSaveCancel); - _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file = null; - FlxG.log.notice("Successfully saved LEVEL DATA."); + if(FlxG.save.data.distractions){ + 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(); + }); + } } - /** - * Called when the save file dialog is cancelled. - */ - function onSaveCancel(_):Void + var trainMoving:Bool = false; + var trainFrameTiming:Float = 0; + + var trainCars:Int = 8; + var trainFinishing:Bool = false; + var trainCooldown:Int = 0; + + function trainStart():Void { - _file.removeEventListener(Event.COMPLETE, onSaveComplete); - _file.removeEventListener(Event.CANCEL, onSaveCancel); - _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file = null; + if(FlxG.save.data.distractions){ + trainMoving = true; + if (!trainSound.playing) + trainSound.play(true); + } } - /** - * Called if there is an error while saving the gameplay recording. - */ - function onSaveError(_):Void + var startedMoving:Bool = false; + + function updateTrainPos():Void { - _file.removeEventListener(Event.COMPLETE, onSaveComplete); - _file.removeEventListener(Event.CANCEL, onSaveCancel); - _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file = null; - FlxG.log.error("Problem saving Level data"); + if(FlxG.save.data.distractions){ + 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 + { + if(FlxG.save.data.distractions){ + 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 windows + if (executeModchart && luaModchart != null) + { + luaModchart.setVar('curStep',curStep); + luaModchart.executeState('stepHit',[curStep]); + } + #end + + if (dad.curCharacter == 'spooky' && curStep % 4 == 2) + { + // dad.dance(); + } + + + // yes this updates every step. + // yes this is bad + // but i'm doing it to update misses and accuracy + #if windows + // 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 + ") " + Ratings.GenerateLetterRank(accuracy), "Acc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC,true, songLength - Conductor.songPosition); + #end + + } + + var lightningStrikeBeat:Int = 0; + var lightningOffset:Int = 8; + + override function beatHit() + { + super.beatHit(); + + if (generatedMusic) + { + notes.sort(FlxSort.byY, (FlxG.save.data.downscroll ? FlxSort.ASCENDING : FlxSort.DESCENDING)); + } + + #if windows + if (executeModchart && luaModchart != null) + { + luaModchart.setVar('curBeat',curBeat); + luaModchart.executeState('beatHit',[curBeat]); + } + #end + + 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 + + // Commented out until a reason to bring this back arises in the future + /* if (SONG.notes[Math.floor(curStep / 16)].mustHitSection) + dad.dance(); */ + + if(dad.animation.curAnim.name.startsWith('sing')) + if(dad.animation.finished) + dad.dance(); + else + 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': + if(FlxG.save.data.distractions){ + bgGirls.dance(); + } + + case 'mall': + if(FlxG.save.data.distractions){ + upperBoppers.animation.play('bop', true); + bottomBoppers.animation.play('bop', true); + santa.animation.play('idle', true); + } + + case 'limo': + if(FlxG.save.data.distractions){ + grpLimoDancers.forEach(function(dancer:BackgroundDancer) + { + dancer.dance(); + }); + + if (FlxG.random.bool(10) && fastCarCanDrive) + fastCarDrive(); + } + case "philly": + if(FlxG.save.data.distractions){ + 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) + { + if(FlxG.save.data.distractions){ + trainCooldown = FlxG.random.int(-4, 0); + trainStart(); + } + } + } + + if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset) + { + if(FlxG.save.data.distractions){ + lightningStrikeShit(); + } + } + } + + var curLight:Int = 0; } From d450176249f5a97f48ce8416a0ce587ebaa85eac Mon Sep 17 00:00:00 2001 From: Prokube <68293280+prokube@users.noreply.github.com> Date: Tue, 4 May 2021 07:48:29 -0700 Subject: [PATCH 4/4] added labels in the Sections tab also put " Data" at the end of literally every tab because ??? --- source/ChartingState.hx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source/ChartingState.hx b/source/ChartingState.hx index 104763f..93c5cfa 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -162,8 +162,8 @@ class ChartingState extends MusicBeatState add(dummyArrow); var tabs = [ - {name: "Song", label: 'Song'}, - {name: "Section", label: 'Section'}, + {name: "Song", label: 'Song Data'}, + {name: "Section", label: 'Section Data'}, {name: "Note", label: 'Note Data'}, {name: "Assets", label: 'Assets'} ]; @@ -348,20 +348,23 @@ class ChartingState extends MusicBeatState stepperLength.value = _song.notes[curSection].lengthInSteps; stepperLength.name = "section_length"; + var stepperLengthLabel = new FlxText(74,10,'Section Length (in steps)'); + stepperSectionBPM = new FlxUINumericStepper(10, 80, 1, Conductor.bpm, 0, 999, 0); stepperSectionBPM.value = Conductor.bpm; stepperSectionBPM.name = 'section_bpm'; - var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 130, 1, 1, -999, 999, 0); + var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 132, 1, 1, -999, 999, 0); + var stepperCopyLabel = new FlxText(174,132,'sections back'); var copyButton:FlxButton = new FlxButton(10, 130, "Copy last section", function() { copySection(Std.int(stepperCopy.value)); }); - var clearSectionButton:FlxButton = new FlxButton(10, 150, "Clear", clearSection); + var clearSectionButton:FlxButton = new FlxButton(10, 150, "Clear Section", clearSection); - var swapSection:FlxButton = new FlxButton(10, 170, "Swap section", function() + var swapSection:FlxButton = new FlxButton(10, 170, "Swap Section", function() { for (i in 0..._song.notes[curSection].sectionNotes.length) { @@ -371,21 +374,22 @@ class ChartingState extends MusicBeatState updateGrid(); } }); - - check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Must hit section", 100); + check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Camera Points to P1?", 100); check_mustHitSection.name = 'check_mustHit'; check_mustHitSection.checked = true; // _song.needsVoices = check_mustHit.checked; - check_altAnim = new FlxUICheckBox(10, 400, null, null, "Alt Animation", 100); + check_altAnim = new FlxUICheckBox(10, 400, null, null, "Alternate Animation", 100); check_altAnim.name = 'check_altAnim'; check_changeBPM = new FlxUICheckBox(10, 60, null, null, 'Change BPM', 100); check_changeBPM.name = 'check_changeBPM'; tab_group_section.add(stepperLength); + tab_group_section.add(stepperLengthLabel); tab_group_section.add(stepperSectionBPM); tab_group_section.add(stepperCopy); + tab_group_section.add(stepperCopyLabel); tab_group_section.add(check_mustHitSection); tab_group_section.add(check_altAnim); tab_group_section.add(check_changeBPM);