From f3c7b544011c4e0b95d387cd6b3975db74013d43 Mon Sep 17 00:00:00 2001 From: JordanSantiagoYT <61796448+JordanSantiagoYT@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:19:13 -0400 Subject: [PATCH] YEAHHH 1. Fixed icons not showing properly if you had Opponent Chart turned on 2. Fixed winning icons not playing (because of the previous commit) 3. The guns ascension now accounts for if you're playing as the opponent or not --- source/ClientPrefs.hx | 1704 +-- source/CreditsState.hx | 676 +- source/FreeplayState.hx | 1452 +- source/GameplayChangersSubstate.hx | 1296 +- source/Main.hx | 458 +- source/Paths.hx | 1320 +- source/PauseSubState.hx | 852 +- source/PlayState.hx | 19703 ++++++++++++++------------- source/Song.hx | 296 +- source/TitleState.hx | 1622 +-- 10 files changed, 14708 insertions(+), 14671 deletions(-) diff --git a/source/ClientPrefs.hx b/source/ClientPrefs.hx index ffd1ece6a96..446f806812c 100644 --- a/source/ClientPrefs.hx +++ b/source/ClientPrefs.hx @@ -1,852 +1,852 @@ -package; - -import flixel.FlxG; -import flixel.util.FlxSave; -import flixel.input.keyboard.FlxKey; -import flixel.graphics.FlxGraphic; -import Controls; - -class ClientPrefs { //default settings if it can't find a save file containing your current settings - public static var downScroll:Bool = false; - public static var middleScroll:Bool = false; - public static var mobileMidScroll:Bool = false; - public static var opponentStrums:Bool = true; - public static var showFPS:Bool = true; - public static var flashing:Bool = true; - public static var globalAntialiasing:Bool = true; - public static var healthDisplay:Bool = true; - public static var ghostTapAnim:Bool = true; - public static var spaceVPose:Bool = true; - public static var cameraPanning:Bool = true; - public static var colorQuants:Bool = false; - public static var panIntensity:Float = 1; - public static var noteSplashes:Bool = true; - public static var enableColorShader:Bool = true; - public static var cacheOnGPU:Bool = false; - public static var communityGameBot:Bool = false; - public static var noSyncing:Bool = false; - public static var startingSync:Bool = false; - public static var playerLightStrum:Bool = true; - public static var progAudioLoad:Bool = false; - public static var oppNoteSplashes:Bool = true; - public static var instaRestart:Bool = false; - public static var charsAndBG:Bool = true; - public static var lowQuality:Bool = false; - public static var shaders:Bool = true; - public static var framerate:Int = 60; - public static var cursing:Bool = true; - public static var maxSplashLimit:Int = 16; - public static var showMaxScore:Bool = true; - public static var longHPBar:Bool = false; - public static var moreMaxHP:Bool = false; - public static var songPercentage:Bool = true; - public static var autosaveInterval:Float = 5.0; - public static var noteMotionBlur:Bool = false; - public static var noteMBMult:Float = 1; - public static var comboMultLimit:Float = 5; - public static var minCGBMS:Int = 5; - public static var maxCGBMS:Int = 5; - public static var autosaveCharts:Bool = true; - public static var antiCheatEnable:Bool = false; - public static var showRamUsage:Bool = true; - public static var showMaxRamUsage:Bool = true; - public static var rainbowNotes:Bool = false; - public static var bfIconStyle:String = 'Default'; - public static var noteStyleThing:String = 'Default'; - public static var daMenuMusic:String = 'Mashup'; - public static var ratingIntensity:String = 'Normal'; - public static var autoPause:Bool = true; - public static var randomBotplayText:Bool = true; - public static var opponentLightStrum:Bool = true; - public static var complexAccuracy:Bool = false; - public static var resyncType:String = 'Psych'; - public static var scoreTxtSize:Int = 0; - public static var botLightStrum:Bool = true; - public static var violence:Bool = true; - public static var camZooms:Bool = true; - public static var showNotes:Bool = true; - public static var doubleGhost:Bool = true; - public static var songLoading:Bool = true; - public static var resultsScreen:Bool = true; - public static var botTxtFade:Bool = true; - public static var hideHud:Bool = false; - public static var debugInfo:Bool = false; - public static var hideScore:Bool = false; - public static var voiidTrollMode:Bool = false; - public static var compactNumbers:Bool = false; - public static var ezSpam:Bool = false; - public static var longFCName:Bool = false; - public static var holdNoteHits:Bool = false; - public static var comboScoreEffect:Bool = false; - public static var noGunsRNG:Bool = false; - public static var comboMultiType:String = 'osu!'; - public static var noteOffset:Int = 0; - public static var arrowHSV:Array> = [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]; - public static var ghostTapping:Bool = true; - public static var communityGameMode:Bool = false; - public static var wrongCameras:Bool = false; - public static var pbRControls:Bool = false; - public static var shitGivesMiss:Bool = false; - public static var trollMaxSpeed:String = 'Medium'; - public static var timebarShowSpeed:Bool = false; - public static var noteSpawnTime:Float = 1; - public static var dynamicSpawnTime:Bool = false; - public static var evenLessBotLag:Bool = false; - public static var showcaseMode:Bool = false; - public static var oppNoteAlpha:Float = 0.65; - public static var lessBotLag:Bool = false; - public static var ratesAndCombo:Bool = false; - public static var showNPS:Bool = false; - public static var showMS:Bool = false; - public static var comboPopup:Bool = false; - public static var ratingCounter:Bool = false; - public static var memLeaks:Bool = false; - public static var noPausing:Bool = false; - public static var doubleGhostZoom:Bool = true; - public static var npsWithSpeed:Bool = true; - public static var moreSpecificSpeed:Bool = true; - public static var lengthIntro:Bool = true; - public static var opponentRateCount:Bool = true; - public static var coolGameplay:Bool = false; - public static var skipResultsScreen:Bool = false; - public static var hudType:String = 'Kade Engine'; - public static var smoothHealth:Bool = true; - public static var smoothHealthType:String = 'Golden Apple 1.5'; - public static var rateNameStuff:String = 'Quotes'; - public static var timeBounce:Bool = true; - public static var percentDecimals:Int = 2; - public static var healthGainType:String = 'Psych Engine'; - public static var hitsoundType:String = 'osu!mania'; - public static var splashType:String = 'Psych Engine'; - public static var iconBounceType:String = 'Golden Apple'; - public static var ratingType:String = 'Base FNF'; - public static var timeBarType:String = 'Time Left'; - public static var marvRateColor:String = 'Golden'; - public static var noMarvJudge:Bool = false; - public static var zeroHealthLimit:Bool = false; - public static var scoreZoom:Bool = true; - public static var goldSickSFC:Bool = true; - public static var colorRatingFC:Bool = false; - public static var colorRatingHit:Bool = true; - public static var missSoundShit:Bool = false; - public static var noReset:Bool = false; - public static var healthBarAlpha:Float = 1; - public static var laneUnderlayAlpha:Float = 1; - public static var laneUnderlay:Bool = false; - public static var controllerMode:Bool = #if android true #else false #end; - public static var hitsoundVolume:Float = 0; - public static var pauseMusic:String = 'Tea Time'; - public static var checkForUpdates:Bool = true; - public static var comboStacking = true; - public static var gameplaySettings:Map = [ - 'scrollspeed' => 1.0, - 'scrolltype' => 'multiplicative', - // anyone reading this, amod is multiplicative speed mod, cmod is constant speed mod, and xmod is bpm based speed mod. - // an amod example would be chartSpeed * multiplier - // cmod would just be constantSpeed = chartSpeed - // and xmod basically works by basing the speed on the bpm. - // iirc (beatsPerSecond * (conductorToNoteDifference / 1000)) * noteSize (110 or something like that depending on it, prolly just use note.height) - // bps is calculated by bpm / 60 - // oh yeah and you'd have to actually convert the difference to seconds which I already do, because this is based on beats and stuff. but it should work - // just fine. but I wont implement it because I don't know how you handle sustains and other stuff like that. - // oh yeah when you calculate the bps divide it by the songSpeed or rate because it wont scroll correctly when speeds exist. - 'songspeed' => 1.0, - 'healthgain' => 1.0, - 'healthloss' => 1.0, - 'instakill' => false, - 'onlySicks' => false, - 'practice' => false, - 'botplay' => false, - 'randommode' => false, - 'opponentplay' => false, - 'opponentdrain' => false, - 'drainlevel' => 1, - 'flip' => false, - 'stairmode' => false, - 'wavemode' => false, - 'onekey' => false, - 'jacks' => 0, - 'randomspeed' => false, - 'bothSides' => false, - 'thetrollingever' => false - ]; - - public static var comboOffset:Array = [0, 0, 0, 0]; - public static var ratingOffset:Int = 0; - public static var marvWindow:Int = 15; - public static var sickWindow:Int = 45; - public static var goodWindow:Int = 90; - public static var badWindow:Int = 135; - public static var safeFrames:Float = 10; - - //Every key has two binds, add your key bind down here and then add your control on options/ControlsSubState.hx and Controls.hx - public static var keyBinds:Map> = [ - //Key Bind, Name for ControlsSubState - 'note_left' => [A, LEFT], - 'note_down' => [S, DOWN], - 'note_up' => [W, UP], - 'note_right' => [D, RIGHT], - - 'ui_left' => [A, LEFT], - 'ui_down' => [S, DOWN], - 'ui_up' => [W, UP], - 'ui_right' => [D, RIGHT], - - 'accept' => [SPACE, ENTER], - 'back' => [BACKSPACE, ESCAPE], - 'pause' => [ENTER, ESCAPE], - 'reset' => [R, NONE], - - 'volume_mute' => [ZERO, NONE], - 'volume_up' => [NUMPADPLUS, PLUS], - 'volume_down' => [NUMPADMINUS, MINUS], - - 'debug_1' => [SEVEN, NONE], - 'debug_2' => [EIGHT, NONE], - 'qt_taunt' => [SPACE, NONE] - ]; - public static var defaultKeys:Map> = null; - - public static function loadDefaultKeys() { - defaultKeys = keyBinds.copy(); - //trace(defaultKeys); - } - - public static function saveSettings() { //changes settings when you exit so that it doesn't reset every time you close the game - FlxG.save.data.downScroll = downScroll; - FlxG.save.data.middleScroll = middleScroll; - FlxG.save.data.mobileMidScroll = mobileMidScroll; - FlxG.save.data.opponentStrums = opponentStrums; - FlxG.save.data.showFPS = showFPS; - FlxG.save.data.flashing = flashing; - FlxG.save.data.globalAntialiasing = globalAntialiasing; - FlxG.save.data.noteSplashes = noteSplashes; - FlxG.save.data.oppNoteSplashes = oppNoteSplashes; - FlxG.save.data.songLoading = songLoading; - FlxG.save.data.debugInfo = debugInfo; - FlxG.save.data.scoreTxtSize = scoreTxtSize; - FlxG.save.data.lowQuality = lowQuality; - FlxG.save.data.shaders = shaders; - FlxG.save.data.ezSpam = ezSpam; - FlxG.save.data.evenLessBotLag = evenLessBotLag; - FlxG.save.data.framerate = framerate; - //FlxG.save.data.cursing = cursing; - //FlxG.save.data.violence = violence; - FlxG.save.data.progAudioLoad = progAudioLoad; - FlxG.save.data.noGunsRNG = noGunsRNG; - FlxG.save.data.camZooms = camZooms; - FlxG.save.data.daMenuMusic = daMenuMusic; - FlxG.save.data.maxSplashLimit = maxSplashLimit; - FlxG.save.data.showMaxScore = showMaxScore; - FlxG.save.data.autosaveInterval = autosaveInterval; - FlxG.save.data.autosaveCharts = autosaveCharts; - FlxG.save.data.rateNameStuff = rateNameStuff; - FlxG.save.data.longFCName = longFCName; - FlxG.save.data.botTxtFade = botTxtFade; - FlxG.save.data.noteMotionBlur = noteMotionBlur; - FlxG.save.data.noteMBMult = noteMBMult; - FlxG.save.data.showNotes = showNotes; - FlxG.save.data.skipResultsScreen = skipResultsScreen; - FlxG.save.data.timeBounce = timeBounce; - FlxG.save.data.maxCGBMS = maxCGBMS; - FlxG.save.data.minCGBMS = minCGBMS; - FlxG.save.data.showRamUsage = showRamUsage; - FlxG.save.data.showMaxRamUsage = showMaxRamUsage; - FlxG.save.data.playerLightStrum = playerLightStrum; - FlxG.save.data.healthDisplay = healthDisplay; - FlxG.save.data.wrongCameras = wrongCameras; - FlxG.save.data.autoPause = autoPause; - FlxG.save.data.holdNoteHits = holdNoteHits; - FlxG.save.data.comboScoreEffect = comboScoreEffect; - FlxG.save.data.comboMultiType = comboMultiType; - FlxG.save.data.charsAndBG = charsAndBG; - FlxG.save.data.pbRControls = pbRControls; - FlxG.save.data.doubleGhost = doubleGhost; - FlxG.save.data.bfIconStyle = bfIconStyle; - FlxG.save.data.noteStyleThing = noteStyleThing; - FlxG.save.data.antiCheatEnable = antiCheatEnable; - FlxG.save.data.randomBotplayText = randomBotplayText; - FlxG.save.data.showNPS = showNPS; - FlxG.save.data.startingSync = startingSync; - FlxG.save.data.noSyncing = noSyncing; - FlxG.save.data.resultsScreen = resultsScreen; - FlxG.save.data.instaRestart = instaRestart; - FlxG.save.data.percentDecimals = percentDecimals; - FlxG.save.data.comboMultLimit = comboMultLimit; - FlxG.save.data.iconBounceType = iconBounceType; - FlxG.save.data.cameraPanning = cameraPanning; - FlxG.save.data.panIntensity = panIntensity; - FlxG.save.data.voiidTrollMode = voiidTrollMode; - FlxG.save.data.complexAccuracy = complexAccuracy; - FlxG.save.data.resyncType = resyncType; - FlxG.save.data.compactNumbers = compactNumbers; - FlxG.save.data.colorQuants = colorQuants; - FlxG.save.data.noteSpawnTime = noteSpawnTime; - FlxG.save.data.cacheOnGPU = cacheOnGPU; - FlxG.save.data.hideScore = hideScore; - FlxG.save.data.doubleGhostZoom = doubleGhostZoom; - FlxG.save.data.memLeaks = memLeaks; - FlxG.save.data.communityGameBot = communityGameBot; - FlxG.save.data.dynamicSpawnTime = dynamicSpawnTime; - FlxG.save.data.botLightStrum = botLightStrum; - FlxG.save.data.opponentLightStrum = opponentLightStrum; - FlxG.save.data.opponentRateCount = opponentRateCount; - FlxG.save.data.zeroHealthLimit = zeroHealthLimit; - FlxG.save.data.hitsoundType = hitsoundType; - FlxG.save.data.hudType = hudType; - FlxG.save.data.ratingCounter = ratingCounter; - FlxG.save.data.colorRatingHit = colorRatingHit; - FlxG.save.data.rainbowNotes = rainbowNotes; - FlxG.save.data.healthGainType = healthGainType; - FlxG.save.data.oppNoteAlpha = oppNoteAlpha; - FlxG.save.data.enableColorShader = enableColorShader; - FlxG.save.data.noPausing = noPausing; - FlxG.save.data.noteOffset = noteOffset; - FlxG.save.data.ratesAndCombo = ratesAndCombo; - FlxG.save.data.ratingType = ratingType; - FlxG.save.data.showMS = showMS; - FlxG.save.data.comboPopup = comboPopup; - FlxG.save.data.ratingIntensity = ratingIntensity; - FlxG.save.data.hideHud = hideHud; - FlxG.save.data.lengthIntro = lengthIntro; - FlxG.save.data.arrowHSV = arrowHSV; - FlxG.save.data.longHPBar = longHPBar; - FlxG.save.data.moreMaxHP = moreMaxHP; - FlxG.save.data.npsWithSpeed = npsWithSpeed; - FlxG.save.data.timebarShowSpeed = timebarShowSpeed; - FlxG.save.data.trollMaxSpeed = trollMaxSpeed; - FlxG.save.data.smoothHealthType = smoothHealthType; - FlxG.save.data.smoothHealth = smoothHealth; - FlxG.save.data.moreSpecificSpeed = moreSpecificSpeed; - FlxG.save.data.spaceVPose = spaceVPose; - FlxG.save.data.ghostTapAnim = ghostTapAnim; - FlxG.save.data.ghostTapping = ghostTapping; - FlxG.save.data.communityGameMode = communityGameMode; - FlxG.save.data.lessBotLag = lessBotLag; - FlxG.save.data.songPercentage = songPercentage; - FlxG.save.data.coolGameplay = coolGameplay; - FlxG.save.data.timeBarType = timeBarType; - FlxG.save.data.marvRateColor = marvRateColor; - FlxG.save.data.noMarvJudge = noMarvJudge; - FlxG.save.data.goldSickSFC = goldSickSFC; - FlxG.save.data.colorRatingFC = colorRatingFC; - FlxG.save.data.missSoundShit = missSoundShit; - FlxG.save.data.splashType = splashType; - FlxG.save.data.scoreZoom = scoreZoom; - FlxG.save.data.noReset = noReset; - FlxG.save.data.shitGivesMiss = shitGivesMiss; - FlxG.save.data.healthBarAlpha = healthBarAlpha; - FlxG.save.data.laneUnderlayAlpha = laneUnderlayAlpha; - FlxG.save.data.laneUnderlay = laneUnderlay; - FlxG.save.data.comboOffset = comboOffset; - FlxG.save.data.achievementsMap = Achievements.achievementsMap; - FlxG.save.data.henchmenDeath = Achievements.henchmenDeath; - FlxG.save.data.showcaseMode = showcaseMode; - FlxG.save.data.ratingOffset = ratingOffset; - FlxG.save.data.marvWindow = marvWindow; - FlxG.save.data.sickWindow = sickWindow; - FlxG.save.data.goodWindow = goodWindow; - FlxG.save.data.badWindow = badWindow; - FlxG.save.data.safeFrames = safeFrames; - FlxG.save.data.gameplaySettings = gameplaySettings; - FlxG.save.data.controllerMode = controllerMode; - FlxG.save.data.hitsoundVolume = hitsoundVolume; - FlxG.save.data.pauseMusic = pauseMusic; - FlxG.save.data.checkForUpdates = checkForUpdates; - FlxG.save.data.comboStacking = comboStacking; - - FlxG.save.flush(); - - var save:FlxSave = new FlxSave(); - save.bind('controls_v2', CoolUtil.getSavePath()); //Placing this in a separate save so that it can be manually deleted without removing your Score and stuff - save.data.customControls = keyBinds; - save.flush(); - FlxG.log.add("Settings saved!"); - } - - public static function loadPrefs() { //loads settings if it finds a save file containing the settings - if(FlxG.save.data.downScroll != null) { - downScroll = FlxG.save.data.downScroll; - } - if(FlxG.save.data.middleScroll != null) { - middleScroll = FlxG.save.data.middleScroll; - } - if(FlxG.save.data.mobileMidScroll != null) { - mobileMidScroll = FlxG.save.data.mobileMidScroll; - } - if(FlxG.save.data.opponentStrums != null) { - opponentStrums = FlxG.save.data.opponentStrums; - } - if(FlxG.save.data.showFPS != null) { - showFPS = FlxG.save.data.showFPS; - if(Main.fpsVar != null) { - Main.fpsVar.visible = showFPS; - } - } - if(FlxG.save.data.flashing != null) { - flashing = FlxG.save.data.flashing; - } - if(FlxG.save.data.debugInfo != null) { - debugInfo = FlxG.save.data.debugInfo; - } - if(FlxG.save.data.scoreTxtSize != null) { - scoreTxtSize = FlxG.save.data.scoreTxtSize; - } - if(FlxG.save.data.ezSpam != null) { - ezSpam = FlxG.save.data.ezSpam; - } - if(FlxG.save.data.progAudioLoad != null) { - progAudioLoad = FlxG.save.data.progAudioLoad; - } - if(FlxG.save.data.rateNameStuff != null) { - rateNameStuff = FlxG.save.data.rateNameStuff; - } - if(FlxG.save.data.showMaxScore != null) { - showMaxScore = FlxG.save.data.showMaxScore; - } - if(FlxG.save.data.maxSplashLimit != null) { - maxSplashLimit = FlxG.save.data.maxSplashLimit; - } - if(FlxG.save.data.communityGameBot != null) { - communityGameBot = FlxG.save.data.communityGameBot; - } - if(FlxG.save.data.noGunsRNG != null) { - noGunsRNG = FlxG.save.data.noGunsRNG; - } - if(FlxG.save.data.showRamUsage != null) { - showRamUsage = FlxG.save.data.showRamUsage; - } - if(FlxG.save.data.showMaxRamUsage != null) { - showMaxRamUsage = FlxG.save.data.showMaxRamUsage; - } - if(FlxG.save.data.colorQuants != null) { - colorQuants = FlxG.save.data.colorQuants; - } - if(FlxG.save.data.pbRControls != null) { - pbRControls = FlxG.save.data.pbRControls; - } - if(FlxG.save.data.cameraPanning != null) { - cameraPanning = FlxG.save.data.cameraPanning; - } - if(FlxG.save.data.botTxtFade != null) { - botTxtFade = FlxG.save.data.botTxtFade; - } - if(FlxG.save.data.startingSync != null) { - startingSync = FlxG.save.data.startingSync; - } - if(FlxG.save.data.noSyncing != null) { - noSyncing = FlxG.save.data.noSyncing; - } - if(FlxG.save.data.songLoading != null) { - songLoading = FlxG.save.data.songLoading; - } - if(FlxG.save.data.panIntensity != null) { - panIntensity = FlxG.save.data.panIntensity; - } - if(FlxG.save.data.ratingIntensity != null) { - ratingIntensity = FlxG.save.data.ratingIntensity; - } - if(FlxG.save.data.playerLightStrum != null) { - playerLightStrum = FlxG.save.data.playerLightStrum; - } - if(FlxG.save.data.complexAccuracy != null) { - complexAccuracy = FlxG.save.data.complexAccuracy; - } - if(FlxG.save.data.resyncType != null) { - resyncType = FlxG.save.data.resyncType; - } - if(FlxG.save.data.rainbowNotes != null) { - rainbowNotes = FlxG.save.data.rainbowNotes; - } - if(FlxG.save.data.noteMotionBlur != null) { - noteMotionBlur = FlxG.save.data.noteMotionBlur; - } - if(FlxG.save.data.noteMBMult != null) { - noteMBMult = FlxG.save.data.noteMBMult; - } - if(FlxG.save.data.comboMultLimit != null) { - comboMultLimit = FlxG.save.data.comboMultLimit; - } - if(FlxG.save.data.enableColorShader != null) { - enableColorShader = FlxG.save.data.enableColorShader; - } - if(FlxG.save.data.showNPS != null) { - showNPS = FlxG.save.data.showNPS; - } - if(FlxG.save.data.resultsScreen != null) { - resultsScreen = FlxG.save.data.resultsScreen; - } - if(FlxG.save.data.globalAntialiasing != null) { - globalAntialiasing = FlxG.save.data.globalAntialiasing; - } - if(FlxG.save.data.ratingType != null) { - ratingType = FlxG.save.data.ratingType; - } - if(FlxG.save.data.charsAndBG != null) { - charsAndBG = FlxG.save.data.charsAndBG; - } - if(FlxG.save.data.showcaseMode != null) { - showcaseMode = FlxG.save.data.showcaseMode; - } - if(FlxG.save.data.autoPause != null) { - autoPause = FlxG.save.data.autoPause; - } - if(FlxG.save.data.voiidTrollMode != null) { - voiidTrollMode = FlxG.save.data.voiidTrollMode; - } - if(FlxG.save.data.minCGBMS != null) { - minCGBMS = FlxG.save.data.minCGBMS; - } - if(FlxG.save.data.maxCGBMS != null) { - maxCGBMS = FlxG.save.data.maxCGBMS; - } - if(FlxG.save.data.compactNumbers != null) { - compactNumbers = FlxG.save.data.compactNumbers; - } - if(FlxG.save.data.npsWithSpeed != null) { - npsWithSpeed = FlxG.save.data.npsWithSpeed; - } - if(FlxG.save.data.skipResultsScreen != null) { - skipResultsScreen = FlxG.save.data.skipResultsScreen; - } - if(FlxG.save.data.cacheOnGPU != null) { - cacheOnGPU = FlxG.save.data.cacheOnGPU; - } - if(FlxG.save.data.bfIconStyle != null) { - bfIconStyle = FlxG.save.data.bfIconStyle; - } - if(FlxG.save.data.autosaveInterval != null) { - autosaveInterval = FlxG.save.data.autosaveInterval; - } - if(FlxG.save.data.autosaveCharts != null) { - autosaveCharts = FlxG.save.data.autosaveCharts; - } - if(FlxG.save.data.holdNoteHits != null) { - holdNoteHits = FlxG.save.data.holdNoteHits; - } - if(FlxG.save.data.comboScoreEffect != null) { - comboScoreEffect = FlxG.save.data.comboScoreEffect; - } - if(FlxG.save.data.comboMultiType != null) { - comboMultiType = FlxG.save.data.comboMultiType; - } - if(FlxG.save.data.daMenuMusic != null) { - daMenuMusic = FlxG.save.data.daMenuMusic; - } - if(FlxG.save.data.noteStyleThing != null) { - noteStyleThing = FlxG.save.data.noteStyleThing; - } - if(FlxG.save.data.timeBounce != null) { - timeBounce = FlxG.save.data.timeBounce; - } - if(FlxG.save.data.lengthIntro != null) { - lengthIntro = FlxG.save.data.lengthIntro; - } - if(FlxG.save.data.wrongCameras != null) { - wrongCameras = FlxG.save.data.wrongCameras; - } - if(FlxG.save.data.dynamicSpawnTime != null) { - dynamicSpawnTime = FlxG.save.data.dynamicSpawnTime; - } - if(FlxG.save.data.evenLessBotLag != null) { - evenLessBotLag = FlxG.save.data.evenLessBotLag; - } - if(FlxG.save.data.doubleGhostZoom != null) { - doubleGhostZoom = FlxG.save.data.doubleGhostZoom; - } - if(FlxG.save.data.memLeaks != null) { - memLeaks = FlxG.save.data.memLeaks; - } - if(FlxG.save.data.longFCName != null) { - longFCName = FlxG.save.data.longFCName; - } - if(FlxG.save.data.zeroHealthLimit != null) { - zeroHealthLimit = FlxG.save.data.zeroHealthLimit; - } - if(FlxG.save.data.oppNoteAlpha != null) { - oppNoteAlpha = FlxG.save.data.oppNoteAlpha; - } - if(FlxG.save.data.noPausing != null) { - noPausing = FlxG.save.data.noPausing; - } - if(FlxG.save.data.marvRateColor != null) { - marvRateColor = FlxG.save.data.marvRateColor; - } - if(FlxG.save.data.noteSplashes != null) { - noteSplashes = FlxG.save.data.noteSplashes; - } - if(FlxG.save.data.oppNoteSplashes != null) { - oppNoteSplashes = FlxG.save.data.oppNoteSplashes; - } - if(FlxG.save.data.colorRatingHit != null) { - colorRatingHit = FlxG.save.data.colorRatingHit; - } - if(FlxG.save.data.randomBotplayText != null) { - randomBotplayText = FlxG.save.data.randomBotplayText; - } - if(FlxG.save.data.splashType != null) { - splashType = FlxG.save.data.splashType; - } - if(FlxG.save.data.percentDecimals != null) { - percentDecimals = FlxG.save.data.percentDecimals; - } - if(FlxG.save.data.songPercentage != null) { - songPercentage = FlxG.save.data.songPercentage; - } - if(FlxG.save.data.antiCheatEnable != null) { - antiCheatEnable = FlxG.save.data.antiCheatEnable; - } - if(FlxG.save.data.noteSpawnTime != null) { - noteSpawnTime = FlxG.save.data.noteSpawnTime; - } - if(FlxG.save.data.timebarShowSpeed != null) { - timebarShowSpeed = FlxG.save.data.timebarShowSpeed; - } - if(FlxG.save.data.opponentRateCount != null) { - opponentRateCount = FlxG.save.data.opponentRateCount; - } - if(FlxG.save.data.trollMaxSpeed != null) { - trollMaxSpeed = FlxG.save.data.trollMaxSpeed; - } - if(FlxG.save.data.instaRestart != null) { - instaRestart = FlxG.save.data.instaRestart; - } - if(FlxG.save.data.healthDisplay != null) { - healthDisplay = FlxG.save.data.healthDisplay; - } - if(FlxG.save.data.hitsoundType != null) { - hitsoundType = FlxG.save.data.hitsoundType; - } - if(FlxG.save.data.lowQuality != null) { - lowQuality = FlxG.save.data.lowQuality; - } - if(FlxG.save.data.ratingCounter != null) { - ratingCounter = FlxG.save.data.ratingCounter; - } - if(FlxG.save.data.longHPBar != null) { - longHPBar = FlxG.save.data.longHPBar; - } - if(FlxG.save.data.moreMaxHP != null) { - moreMaxHP = FlxG.save.data.moreMaxHP; - } - if(FlxG.save.data.shaders != null) { - shaders = FlxG.save.data.shaders; - } - if(FlxG.save.data.moreSpecificSpeed != null) { - moreSpecificSpeed = FlxG.save.data.moreSpecificSpeed; - } - if(FlxG.save.data.goldSickSFC != null) { - goldSickSFC = FlxG.save.data.goldSickSFC; - } - if(FlxG.save.data.botLightStrum != null) { - botLightStrum = FlxG.save.data.botLightStrum; - } - if(FlxG.save.data.comboPopup != null) { - comboPopup = FlxG.save.data.comboPopup; - } - if(FlxG.save.data.showMS != null) { - showMS = FlxG.save.data.showMS; - } - if(FlxG.save.data.ratesAndCombo != null) { - ratesAndCombo = FlxG.save.data.ratesAndCombo; - } - if(FlxG.save.data.missSoundShit != null) { - missSoundShit = FlxG.save.data.missSoundShit; - } - if(FlxG.save.data.opponentLightStrum != null) { - opponentLightStrum = FlxG.save.data.opponentLightStrum; - } - if(FlxG.save.data.framerate != null) { - framerate = FlxG.save.data.framerate; - if(framerate > FlxG.drawFramerate) { - FlxG.updateFramerate = framerate; - FlxG.drawFramerate = framerate; - } else { - FlxG.drawFramerate = framerate; - FlxG.updateFramerate = framerate; - } - } - /*if(FlxG.save.data.cursing != null) { - cursing = FlxG.save.data.cursing; - } - if(FlxG.save.data.violence != null) { - violence = FlxG.save.data.violence; - }*/ - if(FlxG.save.data.camZooms != null) { - camZooms = FlxG.save.data.camZooms; - } - if(FlxG.save.data.shitGivesMiss != null) { - shitGivesMiss = FlxG.save.data.shitGivesMiss; - } - if(FlxG.save.data.showNotes != null) { - showNotes = FlxG.save.data.showNotes; - } - if(FlxG.save.data.doubleGhost != null) { - doubleGhost = FlxG.save.data.doubleGhost; - } - if(FlxG.save.data.coolGameplay != null) { - coolGameplay = FlxG.save.data.coolGameplay; - } - if(FlxG.save.data.hideHud != null) { - hideHud = FlxG.save.data.hideHud; - } - if(FlxG.save.data.hideScore != null) { - hideScore = FlxG.save.data.hideScore; - } - if(FlxG.save.data.noteOffset != null) { - noteOffset = FlxG.save.data.noteOffset; - } - if(FlxG.save.data.arrowHSV != null) { - arrowHSV = FlxG.save.data.arrowHSV; - } - if(FlxG.save.data.lessBotLag != null) { - lessBotLag = FlxG.save.data.lessBotLag; - } - if(FlxG.save.data.ghostTapping != null) { - ghostTapping = FlxG.save.data.ghostTapping; - } - if(FlxG.save.data.smoothHealthType != null) { - smoothHealthType = FlxG.save.data.smoothHealthType; - } - if(FlxG.save.data.smoothHealth != null) { - smoothHealth = FlxG.save.data.smoothHealth; - } - if(FlxG.save.data.communityGameMode != null) { - communityGameMode = FlxG.save.data.communityGameMode; - } - if(FlxG.save.data.spaceVPose != null) { - spaceVPose = FlxG.save.data.spaceVPose; - } - if(FlxG.save.data.ghostTapAnim != null) { - ghostTapAnim = FlxG.save.data.ghostTapAnim; - } - if(FlxG.save.data.timeBarType != null) { - timeBarType = FlxG.save.data.timeBarType; - } - if(FlxG.save.data.hudType != null) { - hudType = FlxG.save.data.hudType; - } - if(FlxG.save.data.healthGainType != null) { - healthGainType = FlxG.save.data.healthGainType; - } - if(FlxG.save.data.iconBounceType != null) { - iconBounceType = FlxG.save.data.iconBounceType; - } - if(FlxG.save.data.scoreZoom != null) { - scoreZoom = FlxG.save.data.scoreZoom; - } - if(FlxG.save.data.noReset != null) { - noReset = FlxG.save.data.noReset; - } - if(FlxG.save.data.healthBarAlpha != null) { - healthBarAlpha = FlxG.save.data.healthBarAlpha; - } - if(FlxG.save.data.laneUnderlay != null) { - laneUnderlay = FlxG.save.data.laneUnderlay; - } - if(FlxG.save.data.laneUnderlayAlpha != null) { - laneUnderlayAlpha = FlxG.save.data.laneUnderlayAlpha; - } - if(FlxG.save.data.comboOffset != null) { - comboOffset = FlxG.save.data.comboOffset; - } - - if(FlxG.save.data.ratingOffset != null) { - ratingOffset = FlxG.save.data.ratingOffset; - } - if(FlxG.save.data.colorRatingFC != null) { - colorRatingFC = FlxG.save.data.colorRatingFC; - } - if(FlxG.save.data.noMarvJudge != null) { - noMarvJudge = FlxG.save.data.noMarvJudge; - } - if(FlxG.save.data.marvWindow != null) { - marvWindow = FlxG.save.data.marvWindow; - } - if(FlxG.save.data.sickWindow != null) { - sickWindow = FlxG.save.data.sickWindow; - } - if(FlxG.save.data.goodWindow != null) { - goodWindow = FlxG.save.data.goodWindow; - } - if(FlxG.save.data.badWindow != null) { - badWindow = FlxG.save.data.badWindow; - } - if(FlxG.save.data.safeFrames != null) { - safeFrames = FlxG.save.data.safeFrames; - } - if(FlxG.save.data.controllerMode != null) { - controllerMode = FlxG.save.data.controllerMode; - } - if(FlxG.save.data.hitsoundVolume != null) { - hitsoundVolume = FlxG.save.data.hitsoundVolume; - } - if(FlxG.save.data.pauseMusic != null) { - pauseMusic = FlxG.save.data.pauseMusic; - } - if(FlxG.save.data.gameplaySettings != null) - { - var savedMap:Map = FlxG.save.data.gameplaySettings; - for (name => value in savedMap) - { - gameplaySettings.set(name, value); - } - } - - // flixel automatically saves your volume! - if(FlxG.save.data.volume != null) - { - FlxG.sound.volume = FlxG.save.data.volume; - } - if (FlxG.save.data.mute != null) - { - FlxG.sound.muted = FlxG.save.data.mute; - } - if (FlxG.save.data.checkForUpdates != null) - { - checkForUpdates = FlxG.save.data.checkForUpdates; - } - if (FlxG.save.data.comboStacking != null) - comboStacking = FlxG.save.data.comboStacking; - - var save:FlxSave = new FlxSave(); - save.bind('controls_v2', CoolUtil.getSavePath()); - if(save != null && save.data.customControls != null) { - var loadedControls:Map> = save.data.customControls; - for (control => keys in loadedControls) { - keyBinds.set(control, keys); - } - reloadControls(); - } - } - - inline public static function getGameplaySetting(name:String, defaultValue:Dynamic):Dynamic { - return /*PlayState.isStoryMode ? defaultValue : */ (gameplaySettings.exists(name) ? gameplaySettings.get(name) : defaultValue); - } - - public static function reloadControls() { - PlayerSettings.player1.controls.setKeyboardScheme(KeyboardScheme.Solo); - - TitleState.muteKeys = copyKey(keyBinds.get('volume_mute')); - TitleState.volumeDownKeys = copyKey(keyBinds.get('volume_down')); - TitleState.volumeUpKeys = copyKey(keyBinds.get('volume_up')); - FlxG.sound.muteKeys = TitleState.muteKeys; - FlxG.sound.volumeDownKeys = TitleState.volumeDownKeys; - FlxG.sound.volumeUpKeys = TitleState.volumeUpKeys; - } - public static function copyKey(arrayToCopy:Array):Array { - var copiedArray:Array = arrayToCopy.copy(); - var i:Int = 0; - var len:Int = copiedArray.length; - - while (i < len) { - if(copiedArray[i] == NONE) { - copiedArray.remove(NONE); - --i; - } - i++; - len = copiedArray.length; - } - return copiedArray; - } -} +package; + +import flixel.FlxG; +import flixel.util.FlxSave; +import flixel.input.keyboard.FlxKey; +import flixel.graphics.FlxGraphic; +import Controls; + +class ClientPrefs { //default settings if it can't find a save file containing your current settings + public static var downScroll:Bool = false; + public static var middleScroll:Bool = false; + public static var mobileMidScroll:Bool = false; + public static var opponentStrums:Bool = true; + public static var showFPS:Bool = true; + public static var flashing:Bool = true; + public static var globalAntialiasing:Bool = true; + public static var healthDisplay:Bool = true; + public static var ghostTapAnim:Bool = true; + public static var spaceVPose:Bool = true; + public static var cameraPanning:Bool = true; + public static var colorQuants:Bool = false; + public static var panIntensity:Float = 1; + public static var noteSplashes:Bool = true; + public static var enableColorShader:Bool = true; + public static var cacheOnGPU:Bool = false; + public static var communityGameBot:Bool = false; + public static var noSyncing:Bool = false; + public static var startingSync:Bool = false; + public static var playerLightStrum:Bool = true; + public static var progAudioLoad:Bool = false; + public static var oppNoteSplashes:Bool = true; + public static var instaRestart:Bool = false; + public static var charsAndBG:Bool = true; + public static var lowQuality:Bool = false; + public static var shaders:Bool = true; + public static var framerate:Int = 60; + public static var cursing:Bool = true; + public static var maxSplashLimit:Int = 16; + public static var showMaxScore:Bool = true; + public static var longHPBar:Bool = false; + public static var moreMaxHP:Bool = false; + public static var songPercentage:Bool = true; + public static var autosaveInterval:Float = 5.0; + public static var noteMotionBlur:Bool = false; + public static var noteMBMult:Float = 1; + public static var comboMultLimit:Float = 5; + public static var minCGBMS:Int = 5; + public static var maxCGBMS:Int = 5; + public static var autosaveCharts:Bool = true; + public static var antiCheatEnable:Bool = false; + public static var showRamUsage:Bool = true; + public static var showMaxRamUsage:Bool = true; + public static var rainbowNotes:Bool = false; + public static var bfIconStyle:String = 'Default'; + public static var noteStyleThing:String = 'Default'; + public static var daMenuMusic:String = 'Mashup'; + public static var ratingIntensity:String = 'Normal'; + public static var autoPause:Bool = true; + public static var randomBotplayText:Bool = true; + public static var opponentLightStrum:Bool = true; + public static var complexAccuracy:Bool = false; + public static var resyncType:String = 'Psych'; + public static var scoreTxtSize:Int = 0; + public static var botLightStrum:Bool = true; + public static var violence:Bool = true; + public static var camZooms:Bool = true; + public static var showNotes:Bool = true; + public static var doubleGhost:Bool = true; + public static var songLoading:Bool = true; + public static var resultsScreen:Bool = true; + public static var botTxtFade:Bool = true; + public static var hideHud:Bool = false; + public static var debugInfo:Bool = false; + public static var hideScore:Bool = false; + public static var voiidTrollMode:Bool = false; + public static var compactNumbers:Bool = false; + public static var ezSpam:Bool = false; + public static var longFCName:Bool = false; + public static var holdNoteHits:Bool = false; + public static var comboScoreEffect:Bool = false; + public static var noGunsRNG:Bool = false; + public static var comboMultiType:String = 'osu!'; + public static var noteOffset:Int = 0; + public static var arrowHSV:Array> = [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]; + public static var ghostTapping:Bool = true; + public static var communityGameMode:Bool = false; + public static var wrongCameras:Bool = false; + public static var pbRControls:Bool = false; + public static var shitGivesMiss:Bool = false; + public static var trollMaxSpeed:String = 'Medium'; + public static var timebarShowSpeed:Bool = false; + public static var noteSpawnTime:Float = 1; + public static var dynamicSpawnTime:Bool = false; + public static var evenLessBotLag:Bool = false; + public static var showcaseMode:Bool = false; + public static var oppNoteAlpha:Float = 0.65; + public static var lessBotLag:Bool = false; + public static var ratesAndCombo:Bool = false; + public static var showNPS:Bool = false; + public static var showMS:Bool = false; + public static var comboPopup:Bool = false; + public static var ratingCounter:Bool = false; + public static var memLeaks:Bool = false; + public static var noPausing:Bool = false; + public static var doubleGhostZoom:Bool = true; + public static var npsWithSpeed:Bool = true; + public static var moreSpecificSpeed:Bool = true; + public static var lengthIntro:Bool = true; + public static var opponentRateCount:Bool = true; + public static var coolGameplay:Bool = false; + public static var skipResultsScreen:Bool = false; + public static var hudType:String = 'Kade Engine'; + public static var smoothHealth:Bool = true; + public static var smoothHealthType:String = 'Golden Apple 1.5'; + public static var rateNameStuff:String = 'Quotes'; + public static var timeBounce:Bool = true; + public static var percentDecimals:Int = 2; + public static var healthGainType:String = 'Psych Engine'; + public static var hitsoundType:String = 'osu!mania'; + public static var splashType:String = 'Psych Engine'; + public static var iconBounceType:String = 'Golden Apple'; + public static var ratingType:String = 'Base FNF'; + public static var timeBarType:String = 'Time Left'; + public static var marvRateColor:String = 'Golden'; + public static var noMarvJudge:Bool = false; + public static var zeroHealthLimit:Bool = false; + public static var scoreZoom:Bool = true; + public static var goldSickSFC:Bool = true; + public static var colorRatingFC:Bool = false; + public static var colorRatingHit:Bool = true; + public static var missSoundShit:Bool = false; + public static var noReset:Bool = false; + public static var healthBarAlpha:Float = 1; + public static var laneUnderlayAlpha:Float = 1; + public static var laneUnderlay:Bool = false; + public static var controllerMode:Bool = #if android true #else false #end; + public static var hitsoundVolume:Float = 0; + public static var pauseMusic:String = 'Tea Time'; + public static var checkForUpdates:Bool = true; + public static var comboStacking = true; + public static var gameplaySettings:Map = [ + 'scrollspeed' => 1.0, + 'scrolltype' => 'multiplicative', + // anyone reading this, amod is multiplicative speed mod, cmod is constant speed mod, and xmod is bpm based speed mod. + // an amod example would be chartSpeed * multiplier + // cmod would just be constantSpeed = chartSpeed + // and xmod basically works by basing the speed on the bpm. + // iirc (beatsPerSecond * (conductorToNoteDifference / 1000)) * noteSize (110 or something like that depending on it, prolly just use note.height) + // bps is calculated by bpm / 60 + // oh yeah and you'd have to actually convert the difference to seconds which I already do, because this is based on beats and stuff. but it should work + // just fine. but I wont implement it because I don't know how you handle sustains and other stuff like that. + // oh yeah when you calculate the bps divide it by the songSpeed or rate because it wont scroll correctly when speeds exist. + 'songspeed' => 1.0, + 'healthgain' => 1.0, + 'healthloss' => 1.0, + 'instakill' => false, + 'onlySicks' => false, + 'practice' => false, + 'botplay' => false, + 'randommode' => false, + 'opponentplay' => false, + 'opponentdrain' => false, + 'drainlevel' => 1, + 'flip' => false, + 'stairmode' => false, + 'wavemode' => false, + 'onekey' => false, + 'jacks' => 0, + 'randomspeed' => false, + 'bothSides' => false, + 'thetrollingever' => false + ]; + + public static var comboOffset:Array = [0, 0, 0, 0]; + public static var ratingOffset:Int = 0; + public static var marvWindow:Int = 15; + public static var sickWindow:Int = 45; + public static var goodWindow:Int = 90; + public static var badWindow:Int = 135; + public static var safeFrames:Float = 10; + + //Every key has two binds, add your key bind down here and then add your control on options/ControlsSubState.hx and Controls.hx + public static var keyBinds:Map> = [ + //Key Bind, Name for ControlsSubState + 'note_left' => [A, LEFT], + 'note_down' => [S, DOWN], + 'note_up' => [W, UP], + 'note_right' => [D, RIGHT], + + 'ui_left' => [A, LEFT], + 'ui_down' => [S, DOWN], + 'ui_up' => [W, UP], + 'ui_right' => [D, RIGHT], + + 'accept' => [SPACE, ENTER], + 'back' => [BACKSPACE, ESCAPE], + 'pause' => [ENTER, ESCAPE], + 'reset' => [R, NONE], + + 'volume_mute' => [ZERO, NONE], + 'volume_up' => [NUMPADPLUS, PLUS], + 'volume_down' => [NUMPADMINUS, MINUS], + + 'debug_1' => [SEVEN, NONE], + 'debug_2' => [EIGHT, NONE], + 'qt_taunt' => [SPACE, NONE] + ]; + public static var defaultKeys:Map> = null; + + public static function loadDefaultKeys() { + defaultKeys = keyBinds.copy(); + //trace(defaultKeys); + } + + public static function saveSettings() { //changes settings when you exit so that it doesn't reset every time you close the game + FlxG.save.data.downScroll = downScroll; + FlxG.save.data.middleScroll = middleScroll; + FlxG.save.data.mobileMidScroll = mobileMidScroll; + FlxG.save.data.opponentStrums = opponentStrums; + FlxG.save.data.showFPS = showFPS; + FlxG.save.data.flashing = flashing; + FlxG.save.data.globalAntialiasing = globalAntialiasing; + FlxG.save.data.noteSplashes = noteSplashes; + FlxG.save.data.oppNoteSplashes = oppNoteSplashes; + FlxG.save.data.songLoading = songLoading; + FlxG.save.data.debugInfo = debugInfo; + FlxG.save.data.scoreTxtSize = scoreTxtSize; + FlxG.save.data.lowQuality = lowQuality; + FlxG.save.data.shaders = shaders; + FlxG.save.data.ezSpam = ezSpam; + FlxG.save.data.evenLessBotLag = evenLessBotLag; + FlxG.save.data.framerate = framerate; + //FlxG.save.data.cursing = cursing; + //FlxG.save.data.violence = violence; + FlxG.save.data.progAudioLoad = progAudioLoad; + FlxG.save.data.noGunsRNG = noGunsRNG; + FlxG.save.data.camZooms = camZooms; + FlxG.save.data.daMenuMusic = daMenuMusic; + FlxG.save.data.maxSplashLimit = maxSplashLimit; + FlxG.save.data.showMaxScore = showMaxScore; + FlxG.save.data.autosaveInterval = autosaveInterval; + FlxG.save.data.autosaveCharts = autosaveCharts; + FlxG.save.data.rateNameStuff = rateNameStuff; + FlxG.save.data.longFCName = longFCName; + FlxG.save.data.botTxtFade = botTxtFade; + FlxG.save.data.noteMotionBlur = noteMotionBlur; + FlxG.save.data.noteMBMult = noteMBMult; + FlxG.save.data.showNotes = showNotes; + FlxG.save.data.skipResultsScreen = skipResultsScreen; + FlxG.save.data.timeBounce = timeBounce; + FlxG.save.data.maxCGBMS = maxCGBMS; + FlxG.save.data.minCGBMS = minCGBMS; + FlxG.save.data.showRamUsage = showRamUsage; + FlxG.save.data.showMaxRamUsage = showMaxRamUsage; + FlxG.save.data.playerLightStrum = playerLightStrum; + FlxG.save.data.healthDisplay = healthDisplay; + FlxG.save.data.wrongCameras = wrongCameras; + FlxG.save.data.autoPause = autoPause; + FlxG.save.data.holdNoteHits = holdNoteHits; + FlxG.save.data.comboScoreEffect = comboScoreEffect; + FlxG.save.data.comboMultiType = comboMultiType; + FlxG.save.data.charsAndBG = charsAndBG; + FlxG.save.data.pbRControls = pbRControls; + FlxG.save.data.doubleGhost = doubleGhost; + FlxG.save.data.bfIconStyle = bfIconStyle; + FlxG.save.data.noteStyleThing = noteStyleThing; + FlxG.save.data.antiCheatEnable = antiCheatEnable; + FlxG.save.data.randomBotplayText = randomBotplayText; + FlxG.save.data.showNPS = showNPS; + FlxG.save.data.startingSync = startingSync; + FlxG.save.data.noSyncing = noSyncing; + FlxG.save.data.resultsScreen = resultsScreen; + FlxG.save.data.instaRestart = instaRestart; + FlxG.save.data.percentDecimals = percentDecimals; + FlxG.save.data.comboMultLimit = comboMultLimit; + FlxG.save.data.iconBounceType = iconBounceType; + FlxG.save.data.cameraPanning = cameraPanning; + FlxG.save.data.panIntensity = panIntensity; + FlxG.save.data.voiidTrollMode = voiidTrollMode; + FlxG.save.data.complexAccuracy = complexAccuracy; + FlxG.save.data.resyncType = resyncType; + FlxG.save.data.compactNumbers = compactNumbers; + FlxG.save.data.colorQuants = colorQuants; + FlxG.save.data.noteSpawnTime = noteSpawnTime; + FlxG.save.data.cacheOnGPU = cacheOnGPU; + FlxG.save.data.hideScore = hideScore; + FlxG.save.data.doubleGhostZoom = doubleGhostZoom; + FlxG.save.data.memLeaks = memLeaks; + FlxG.save.data.communityGameBot = communityGameBot; + FlxG.save.data.dynamicSpawnTime = dynamicSpawnTime; + FlxG.save.data.botLightStrum = botLightStrum; + FlxG.save.data.opponentLightStrum = opponentLightStrum; + FlxG.save.data.opponentRateCount = opponentRateCount; + FlxG.save.data.zeroHealthLimit = zeroHealthLimit; + FlxG.save.data.hitsoundType = hitsoundType; + FlxG.save.data.hudType = hudType; + FlxG.save.data.ratingCounter = ratingCounter; + FlxG.save.data.colorRatingHit = colorRatingHit; + FlxG.save.data.rainbowNotes = rainbowNotes; + FlxG.save.data.healthGainType = healthGainType; + FlxG.save.data.oppNoteAlpha = oppNoteAlpha; + FlxG.save.data.enableColorShader = enableColorShader; + FlxG.save.data.noPausing = noPausing; + FlxG.save.data.noteOffset = noteOffset; + FlxG.save.data.ratesAndCombo = ratesAndCombo; + FlxG.save.data.ratingType = ratingType; + FlxG.save.data.showMS = showMS; + FlxG.save.data.comboPopup = comboPopup; + FlxG.save.data.ratingIntensity = ratingIntensity; + FlxG.save.data.hideHud = hideHud; + FlxG.save.data.lengthIntro = lengthIntro; + FlxG.save.data.arrowHSV = arrowHSV; + FlxG.save.data.longHPBar = longHPBar; + FlxG.save.data.moreMaxHP = moreMaxHP; + FlxG.save.data.npsWithSpeed = npsWithSpeed; + FlxG.save.data.timebarShowSpeed = timebarShowSpeed; + FlxG.save.data.trollMaxSpeed = trollMaxSpeed; + FlxG.save.data.smoothHealthType = smoothHealthType; + FlxG.save.data.smoothHealth = smoothHealth; + FlxG.save.data.moreSpecificSpeed = moreSpecificSpeed; + FlxG.save.data.spaceVPose = spaceVPose; + FlxG.save.data.ghostTapAnim = ghostTapAnim; + FlxG.save.data.ghostTapping = ghostTapping; + FlxG.save.data.communityGameMode = communityGameMode; + FlxG.save.data.lessBotLag = lessBotLag; + FlxG.save.data.songPercentage = songPercentage; + FlxG.save.data.coolGameplay = coolGameplay; + FlxG.save.data.timeBarType = timeBarType; + FlxG.save.data.marvRateColor = marvRateColor; + FlxG.save.data.noMarvJudge = noMarvJudge; + FlxG.save.data.goldSickSFC = goldSickSFC; + FlxG.save.data.colorRatingFC = colorRatingFC; + FlxG.save.data.missSoundShit = missSoundShit; + FlxG.save.data.splashType = splashType; + FlxG.save.data.scoreZoom = scoreZoom; + FlxG.save.data.noReset = noReset; + FlxG.save.data.shitGivesMiss = shitGivesMiss; + FlxG.save.data.healthBarAlpha = healthBarAlpha; + FlxG.save.data.laneUnderlayAlpha = laneUnderlayAlpha; + FlxG.save.data.laneUnderlay = laneUnderlay; + FlxG.save.data.comboOffset = comboOffset; + FlxG.save.data.achievementsMap = Achievements.achievementsMap; + FlxG.save.data.henchmenDeath = Achievements.henchmenDeath; + FlxG.save.data.showcaseMode = showcaseMode; + FlxG.save.data.ratingOffset = ratingOffset; + FlxG.save.data.marvWindow = marvWindow; + FlxG.save.data.sickWindow = sickWindow; + FlxG.save.data.goodWindow = goodWindow; + FlxG.save.data.badWindow = badWindow; + FlxG.save.data.safeFrames = safeFrames; + FlxG.save.data.gameplaySettings = gameplaySettings; + FlxG.save.data.controllerMode = controllerMode; + FlxG.save.data.hitsoundVolume = hitsoundVolume; + FlxG.save.data.pauseMusic = pauseMusic; + FlxG.save.data.checkForUpdates = checkForUpdates; + FlxG.save.data.comboStacking = comboStacking; + + FlxG.save.flush(); + + var save:FlxSave = new FlxSave(); + save.bind('controls_v2', CoolUtil.getSavePath()); //Placing this in a separate save so that it can be manually deleted without removing your Score and stuff + save.data.customControls = keyBinds; + save.flush(); + FlxG.log.add("Settings saved!"); + } + + public static function loadPrefs() { //loads settings if it finds a save file containing the settings + if(FlxG.save.data.downScroll != null) { + downScroll = FlxG.save.data.downScroll; + } + if(FlxG.save.data.middleScroll != null) { + middleScroll = FlxG.save.data.middleScroll; + } + if(FlxG.save.data.mobileMidScroll != null) { + mobileMidScroll = FlxG.save.data.mobileMidScroll; + } + if(FlxG.save.data.opponentStrums != null) { + opponentStrums = FlxG.save.data.opponentStrums; + } + if(FlxG.save.data.showFPS != null) { + showFPS = FlxG.save.data.showFPS; + if(Main.fpsVar != null) { + Main.fpsVar.visible = showFPS; + } + } + if(FlxG.save.data.flashing != null) { + flashing = FlxG.save.data.flashing; + } + if(FlxG.save.data.debugInfo != null) { + debugInfo = FlxG.save.data.debugInfo; + } + if(FlxG.save.data.scoreTxtSize != null) { + scoreTxtSize = FlxG.save.data.scoreTxtSize; + } + if(FlxG.save.data.ezSpam != null) { + ezSpam = FlxG.save.data.ezSpam; + } + if(FlxG.save.data.progAudioLoad != null) { + progAudioLoad = FlxG.save.data.progAudioLoad; + } + if(FlxG.save.data.rateNameStuff != null) { + rateNameStuff = FlxG.save.data.rateNameStuff; + } + if(FlxG.save.data.showMaxScore != null) { + showMaxScore = FlxG.save.data.showMaxScore; + } + if(FlxG.save.data.maxSplashLimit != null) { + maxSplashLimit = FlxG.save.data.maxSplashLimit; + } + if(FlxG.save.data.communityGameBot != null) { + communityGameBot = FlxG.save.data.communityGameBot; + } + if(FlxG.save.data.noGunsRNG != null) { + noGunsRNG = FlxG.save.data.noGunsRNG; + } + if(FlxG.save.data.showRamUsage != null) { + showRamUsage = FlxG.save.data.showRamUsage; + } + if(FlxG.save.data.showMaxRamUsage != null) { + showMaxRamUsage = FlxG.save.data.showMaxRamUsage; + } + if(FlxG.save.data.colorQuants != null) { + colorQuants = FlxG.save.data.colorQuants; + } + if(FlxG.save.data.pbRControls != null) { + pbRControls = FlxG.save.data.pbRControls; + } + if(FlxG.save.data.cameraPanning != null) { + cameraPanning = FlxG.save.data.cameraPanning; + } + if(FlxG.save.data.botTxtFade != null) { + botTxtFade = FlxG.save.data.botTxtFade; + } + if(FlxG.save.data.startingSync != null) { + startingSync = FlxG.save.data.startingSync; + } + if(FlxG.save.data.noSyncing != null) { + noSyncing = FlxG.save.data.noSyncing; + } + if(FlxG.save.data.songLoading != null) { + songLoading = FlxG.save.data.songLoading; + } + if(FlxG.save.data.panIntensity != null) { + panIntensity = FlxG.save.data.panIntensity; + } + if(FlxG.save.data.ratingIntensity != null) { + ratingIntensity = FlxG.save.data.ratingIntensity; + } + if(FlxG.save.data.playerLightStrum != null) { + playerLightStrum = FlxG.save.data.playerLightStrum; + } + if(FlxG.save.data.complexAccuracy != null) { + complexAccuracy = FlxG.save.data.complexAccuracy; + } + if(FlxG.save.data.resyncType != null) { + resyncType = FlxG.save.data.resyncType; + } + if(FlxG.save.data.rainbowNotes != null) { + rainbowNotes = FlxG.save.data.rainbowNotes; + } + if(FlxG.save.data.noteMotionBlur != null) { + noteMotionBlur = FlxG.save.data.noteMotionBlur; + } + if(FlxG.save.data.noteMBMult != null) { + noteMBMult = FlxG.save.data.noteMBMult; + } + if(FlxG.save.data.comboMultLimit != null) { + comboMultLimit = FlxG.save.data.comboMultLimit; + } + if(FlxG.save.data.enableColorShader != null) { + enableColorShader = FlxG.save.data.enableColorShader; + } + if(FlxG.save.data.showNPS != null) { + showNPS = FlxG.save.data.showNPS; + } + if(FlxG.save.data.resultsScreen != null) { + resultsScreen = FlxG.save.data.resultsScreen; + } + if(FlxG.save.data.globalAntialiasing != null) { + globalAntialiasing = FlxG.save.data.globalAntialiasing; + } + if(FlxG.save.data.ratingType != null) { + ratingType = FlxG.save.data.ratingType; + } + if(FlxG.save.data.charsAndBG != null) { + charsAndBG = FlxG.save.data.charsAndBG; + } + if(FlxG.save.data.showcaseMode != null) { + showcaseMode = FlxG.save.data.showcaseMode; + } + if(FlxG.save.data.autoPause != null) { + autoPause = FlxG.save.data.autoPause; + } + if(FlxG.save.data.voiidTrollMode != null) { + voiidTrollMode = FlxG.save.data.voiidTrollMode; + } + if(FlxG.save.data.minCGBMS != null) { + minCGBMS = FlxG.save.data.minCGBMS; + } + if(FlxG.save.data.maxCGBMS != null) { + maxCGBMS = FlxG.save.data.maxCGBMS; + } + if(FlxG.save.data.compactNumbers != null) { + compactNumbers = FlxG.save.data.compactNumbers; + } + if(FlxG.save.data.npsWithSpeed != null) { + npsWithSpeed = FlxG.save.data.npsWithSpeed; + } + if(FlxG.save.data.skipResultsScreen != null) { + skipResultsScreen = FlxG.save.data.skipResultsScreen; + } + if(FlxG.save.data.cacheOnGPU != null) { + cacheOnGPU = FlxG.save.data.cacheOnGPU; + } + if(FlxG.save.data.bfIconStyle != null) { + bfIconStyle = FlxG.save.data.bfIconStyle; + } + if(FlxG.save.data.autosaveInterval != null) { + autosaveInterval = FlxG.save.data.autosaveInterval; + } + if(FlxG.save.data.autosaveCharts != null) { + autosaveCharts = FlxG.save.data.autosaveCharts; + } + if(FlxG.save.data.holdNoteHits != null) { + holdNoteHits = FlxG.save.data.holdNoteHits; + } + if(FlxG.save.data.comboScoreEffect != null) { + comboScoreEffect = FlxG.save.data.comboScoreEffect; + } + if(FlxG.save.data.comboMultiType != null) { + comboMultiType = FlxG.save.data.comboMultiType; + } + if(FlxG.save.data.daMenuMusic != null) { + daMenuMusic = FlxG.save.data.daMenuMusic; + } + if(FlxG.save.data.noteStyleThing != null) { + noteStyleThing = FlxG.save.data.noteStyleThing; + } + if(FlxG.save.data.timeBounce != null) { + timeBounce = FlxG.save.data.timeBounce; + } + if(FlxG.save.data.lengthIntro != null) { + lengthIntro = FlxG.save.data.lengthIntro; + } + if(FlxG.save.data.wrongCameras != null) { + wrongCameras = FlxG.save.data.wrongCameras; + } + if(FlxG.save.data.dynamicSpawnTime != null) { + dynamicSpawnTime = FlxG.save.data.dynamicSpawnTime; + } + if(FlxG.save.data.evenLessBotLag != null) { + evenLessBotLag = FlxG.save.data.evenLessBotLag; + } + if(FlxG.save.data.doubleGhostZoom != null) { + doubleGhostZoom = FlxG.save.data.doubleGhostZoom; + } + if(FlxG.save.data.memLeaks != null) { + memLeaks = FlxG.save.data.memLeaks; + } + if(FlxG.save.data.longFCName != null) { + longFCName = FlxG.save.data.longFCName; + } + if(FlxG.save.data.zeroHealthLimit != null) { + zeroHealthLimit = FlxG.save.data.zeroHealthLimit; + } + if(FlxG.save.data.oppNoteAlpha != null) { + oppNoteAlpha = FlxG.save.data.oppNoteAlpha; + } + if(FlxG.save.data.noPausing != null) { + noPausing = FlxG.save.data.noPausing; + } + if(FlxG.save.data.marvRateColor != null) { + marvRateColor = FlxG.save.data.marvRateColor; + } + if(FlxG.save.data.noteSplashes != null) { + noteSplashes = FlxG.save.data.noteSplashes; + } + if(FlxG.save.data.oppNoteSplashes != null) { + oppNoteSplashes = FlxG.save.data.oppNoteSplashes; + } + if(FlxG.save.data.colorRatingHit != null) { + colorRatingHit = FlxG.save.data.colorRatingHit; + } + if(FlxG.save.data.randomBotplayText != null) { + randomBotplayText = FlxG.save.data.randomBotplayText; + } + if(FlxG.save.data.splashType != null) { + splashType = FlxG.save.data.splashType; + } + if(FlxG.save.data.percentDecimals != null) { + percentDecimals = FlxG.save.data.percentDecimals; + } + if(FlxG.save.data.songPercentage != null) { + songPercentage = FlxG.save.data.songPercentage; + } + if(FlxG.save.data.antiCheatEnable != null) { + antiCheatEnable = FlxG.save.data.antiCheatEnable; + } + if(FlxG.save.data.noteSpawnTime != null) { + noteSpawnTime = FlxG.save.data.noteSpawnTime; + } + if(FlxG.save.data.timebarShowSpeed != null) { + timebarShowSpeed = FlxG.save.data.timebarShowSpeed; + } + if(FlxG.save.data.opponentRateCount != null) { + opponentRateCount = FlxG.save.data.opponentRateCount; + } + if(FlxG.save.data.trollMaxSpeed != null) { + trollMaxSpeed = FlxG.save.data.trollMaxSpeed; + } + if(FlxG.save.data.instaRestart != null) { + instaRestart = FlxG.save.data.instaRestart; + } + if(FlxG.save.data.healthDisplay != null) { + healthDisplay = FlxG.save.data.healthDisplay; + } + if(FlxG.save.data.hitsoundType != null) { + hitsoundType = FlxG.save.data.hitsoundType; + } + if(FlxG.save.data.lowQuality != null) { + lowQuality = FlxG.save.data.lowQuality; + } + if(FlxG.save.data.ratingCounter != null) { + ratingCounter = FlxG.save.data.ratingCounter; + } + if(FlxG.save.data.longHPBar != null) { + longHPBar = FlxG.save.data.longHPBar; + } + if(FlxG.save.data.moreMaxHP != null) { + moreMaxHP = FlxG.save.data.moreMaxHP; + } + if(FlxG.save.data.shaders != null) { + shaders = FlxG.save.data.shaders; + } + if(FlxG.save.data.moreSpecificSpeed != null) { + moreSpecificSpeed = FlxG.save.data.moreSpecificSpeed; + } + if(FlxG.save.data.goldSickSFC != null) { + goldSickSFC = FlxG.save.data.goldSickSFC; + } + if(FlxG.save.data.botLightStrum != null) { + botLightStrum = FlxG.save.data.botLightStrum; + } + if(FlxG.save.data.comboPopup != null) { + comboPopup = FlxG.save.data.comboPopup; + } + if(FlxG.save.data.showMS != null) { + showMS = FlxG.save.data.showMS; + } + if(FlxG.save.data.ratesAndCombo != null) { + ratesAndCombo = FlxG.save.data.ratesAndCombo; + } + if(FlxG.save.data.missSoundShit != null) { + missSoundShit = FlxG.save.data.missSoundShit; + } + if(FlxG.save.data.opponentLightStrum != null) { + opponentLightStrum = FlxG.save.data.opponentLightStrum; + } + if(FlxG.save.data.framerate != null) { + framerate = FlxG.save.data.framerate; + if(framerate > FlxG.drawFramerate) { + FlxG.updateFramerate = framerate; + FlxG.drawFramerate = framerate; + } else { + FlxG.drawFramerate = framerate; + FlxG.updateFramerate = framerate; + } + } + /*if(FlxG.save.data.cursing != null) { + cursing = FlxG.save.data.cursing; + } + if(FlxG.save.data.violence != null) { + violence = FlxG.save.data.violence; + }*/ + if(FlxG.save.data.camZooms != null) { + camZooms = FlxG.save.data.camZooms; + } + if(FlxG.save.data.shitGivesMiss != null) { + shitGivesMiss = FlxG.save.data.shitGivesMiss; + } + if(FlxG.save.data.showNotes != null) { + showNotes = FlxG.save.data.showNotes; + } + if(FlxG.save.data.doubleGhost != null) { + doubleGhost = FlxG.save.data.doubleGhost; + } + if(FlxG.save.data.coolGameplay != null) { + coolGameplay = FlxG.save.data.coolGameplay; + } + if(FlxG.save.data.hideHud != null) { + hideHud = FlxG.save.data.hideHud; + } + if(FlxG.save.data.hideScore != null) { + hideScore = FlxG.save.data.hideScore; + } + if(FlxG.save.data.noteOffset != null) { + noteOffset = FlxG.save.data.noteOffset; + } + if(FlxG.save.data.arrowHSV != null) { + arrowHSV = FlxG.save.data.arrowHSV; + } + if(FlxG.save.data.lessBotLag != null) { + lessBotLag = FlxG.save.data.lessBotLag; + } + if(FlxG.save.data.ghostTapping != null) { + ghostTapping = FlxG.save.data.ghostTapping; + } + if(FlxG.save.data.smoothHealthType != null) { + smoothHealthType = FlxG.save.data.smoothHealthType; + } + if(FlxG.save.data.smoothHealth != null) { + smoothHealth = FlxG.save.data.smoothHealth; + } + if(FlxG.save.data.communityGameMode != null) { + communityGameMode = FlxG.save.data.communityGameMode; + } + if(FlxG.save.data.spaceVPose != null) { + spaceVPose = FlxG.save.data.spaceVPose; + } + if(FlxG.save.data.ghostTapAnim != null) { + ghostTapAnim = FlxG.save.data.ghostTapAnim; + } + if(FlxG.save.data.timeBarType != null) { + timeBarType = FlxG.save.data.timeBarType; + } + if(FlxG.save.data.hudType != null) { + hudType = FlxG.save.data.hudType; + } + if(FlxG.save.data.healthGainType != null) { + healthGainType = FlxG.save.data.healthGainType; + } + if(FlxG.save.data.iconBounceType != null) { + iconBounceType = FlxG.save.data.iconBounceType; + } + if(FlxG.save.data.scoreZoom != null) { + scoreZoom = FlxG.save.data.scoreZoom; + } + if(FlxG.save.data.noReset != null) { + noReset = FlxG.save.data.noReset; + } + if(FlxG.save.data.healthBarAlpha != null) { + healthBarAlpha = FlxG.save.data.healthBarAlpha; + } + if(FlxG.save.data.laneUnderlay != null) { + laneUnderlay = FlxG.save.data.laneUnderlay; + } + if(FlxG.save.data.laneUnderlayAlpha != null) { + laneUnderlayAlpha = FlxG.save.data.laneUnderlayAlpha; + } + if(FlxG.save.data.comboOffset != null) { + comboOffset = FlxG.save.data.comboOffset; + } + + if(FlxG.save.data.ratingOffset != null) { + ratingOffset = FlxG.save.data.ratingOffset; + } + if(FlxG.save.data.colorRatingFC != null) { + colorRatingFC = FlxG.save.data.colorRatingFC; + } + if(FlxG.save.data.noMarvJudge != null) { + noMarvJudge = FlxG.save.data.noMarvJudge; + } + if(FlxG.save.data.marvWindow != null) { + marvWindow = FlxG.save.data.marvWindow; + } + if(FlxG.save.data.sickWindow != null) { + sickWindow = FlxG.save.data.sickWindow; + } + if(FlxG.save.data.goodWindow != null) { + goodWindow = FlxG.save.data.goodWindow; + } + if(FlxG.save.data.badWindow != null) { + badWindow = FlxG.save.data.badWindow; + } + if(FlxG.save.data.safeFrames != null) { + safeFrames = FlxG.save.data.safeFrames; + } + if(FlxG.save.data.controllerMode != null) { + controllerMode = FlxG.save.data.controllerMode; + } + if(FlxG.save.data.hitsoundVolume != null) { + hitsoundVolume = FlxG.save.data.hitsoundVolume; + } + if(FlxG.save.data.pauseMusic != null) { + pauseMusic = FlxG.save.data.pauseMusic; + } + if(FlxG.save.data.gameplaySettings != null) + { + var savedMap:Map = FlxG.save.data.gameplaySettings; + for (name => value in savedMap) + { + gameplaySettings.set(name, value); + } + } + + // flixel automatically saves your volume! + if(FlxG.save.data.volume != null) + { + FlxG.sound.volume = FlxG.save.data.volume; + } + if (FlxG.save.data.mute != null) + { + FlxG.sound.muted = FlxG.save.data.mute; + } + if (FlxG.save.data.checkForUpdates != null) + { + checkForUpdates = FlxG.save.data.checkForUpdates; + } + if (FlxG.save.data.comboStacking != null) + comboStacking = FlxG.save.data.comboStacking; + + var save:FlxSave = new FlxSave(); + save.bind('controls_v2', CoolUtil.getSavePath()); + if(save != null && save.data.customControls != null) { + var loadedControls:Map> = save.data.customControls; + for (control => keys in loadedControls) { + keyBinds.set(control, keys); + } + reloadControls(); + } + } + + inline public static function getGameplaySetting(name:String, defaultValue:Dynamic):Dynamic { + return /*PlayState.isStoryMode ? defaultValue : */ (gameplaySettings.exists(name) ? gameplaySettings.get(name) : defaultValue); + } + + public static function reloadControls() { + PlayerSettings.player1.controls.setKeyboardScheme(KeyboardScheme.Solo); + + TitleState.muteKeys = copyKey(keyBinds.get('volume_mute')); + TitleState.volumeDownKeys = copyKey(keyBinds.get('volume_down')); + TitleState.volumeUpKeys = copyKey(keyBinds.get('volume_up')); + FlxG.sound.muteKeys = TitleState.muteKeys; + FlxG.sound.volumeDownKeys = TitleState.volumeDownKeys; + FlxG.sound.volumeUpKeys = TitleState.volumeUpKeys; + } + public static function copyKey(arrayToCopy:Array):Array { + var copiedArray:Array = arrayToCopy.copy(); + var i:Int = 0; + var len:Int = copiedArray.length; + + while (i < len) { + if(copiedArray[i] == NONE) { + copiedArray.remove(NONE); + --i; + } + i++; + len = copiedArray.length; + } + return copiedArray; + } +} diff --git a/source/CreditsState.hx b/source/CreditsState.hx index 6c675fc44a2..8e81d8eab4a 100644 --- a/source/CreditsState.hx +++ b/source/CreditsState.hx @@ -1,339 +1,339 @@ -package; - -#if desktop -import Discord.DiscordClient; -#end -import flash.text.TextField; -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.addons.display.FlxGridOverlay; -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.math.FlxMath; -import flixel.text.FlxText; -import flixel.util.FlxColor; -import flixel.tweens.FlxTween; -import flixel.tweens.FlxEase; -#if MODS_ALLOWED -import sys.FileSystem; -import sys.io.File; -#end -import lime.utils.Assets; - -using StringTools; - -class CreditsState extends MusicBeatState -{ - var curSelected:Int = -1; - - private var grpOptions:FlxTypedGroup; - private var iconArray:Array = []; - private var creditsStuff:Array> = []; - - var bg:FlxSprite; - var descText:FlxText; - var intendedColor:Int; - var colorTween:FlxTween; - var descBox:AttachedSprite; - - var offsetThing:Float = -75; - - override function create() - { - Paths.clearStoredMemory(); - Paths.clearUnusedMemory(); - - #if desktop - // Updating Discord Rich Presence - DiscordClient.changePresence("In the Menus", null); - #end - - persistentUpdate = true; - bg = new FlxSprite().loadGraphic(Paths.image('menuDesat')); - add(bg); - bg.screenCenter(); - - grpOptions = new FlxTypedGroup(); - add(grpOptions); - - #if MODS_ALLOWED - var path:String = 'modsList.txt'; - if(FileSystem.exists(path)) - { - var leMods:Array = CoolUtil.coolTextFile(path); - for (i in 0...leMods.length) - { - if(leMods.length > 1 && leMods[0].length > 0) { - var modSplit:Array = leMods[i].split('|'); - if(!Paths.ignoreModFolders.contains(modSplit[0].toLowerCase()) && !modsAdded.contains(modSplit[0])) - { - if(modSplit[1] == '1') - pushModCreditsToList(modSplit[0]); - else - modsAdded.push(modSplit[0]); - } - } - } - } - - var arrayOfFolders:Array = Paths.getModDirectories(); - arrayOfFolders.push(''); - for (folder in arrayOfFolders) - { - pushModCreditsToList(folder); - } - #end - - var pisspoop:Array> = [ //Name - Icon name - Description - Link - BG Color - ['JS Engine People'], - ['Jordan Santiago', 'jor', 'Coded everything into JS Engine', 'https://twitter.com/JordansTweetsYT', 'FF9300'], - ['Stefan2008', 'stef', "Granted permission to use the Results Screen code, and helped\nwith the Android version's development", 'https://www.youtube.com/channel/UC9Nwf21GbaEm_h0Ka9gxZjQ', '800080'], - [''], - ['Psych Engine Team'], - ['Shadow Mario', 'shadowmario', 'Main Programmer of Psych Engine', 'https://twitter.com/Shadow_Mario_', '444444'], - ['RiverOaken', 'river', 'Main Artist/Animator of Psych Engine', 'https://twitter.com/RiverOaken', 'B42F71'], - ['shubs', 'shubs', 'Additional Programmer of Psych Engine', 'https://twitter.com/yoshubs', '5E99DF'], - [''], - ['Former Engine Members'], - ['bb-panzu', 'bb', 'Ex-Programmer of Psych Engine', 'https://twitter.com/bbsub3', '3E813A'], - [''], - ['Engine Contributors'], - ['iFlicky', 'flicky', 'Composer of Psync and Tea Time\nMade the Dialogue Sounds', 'https://twitter.com/flicky_i', '9E29CF'], - ['SqirraRNG', 'sqirra', 'Crash Handler and Base code for\nChart Editor\'s Waveform', 'https://twitter.com/gedehari', 'E1843A'], - ['EliteMasterEric', 'mastereric', 'Runtime Shaders support', 'https://twitter.com/EliteMasterEric', 'FFBD40'], - ['PolybiusProxy', 'proxy', '.MP4 Video Loader Library (hxCodec)', 'https://twitter.com/polybiusproxy', 'DCD294'], - ['KadeDev', 'kade', 'Fixed some cool stuff on Chart Editor\nand other PRs', 'https://twitter.com/kade0912', '64A250'], - ['Keoiki', 'keoiki', 'Note Splash Animations', 'https://twitter.com/Keoiki_', 'D2D2D2'], - ['Nebula the Zorua', 'nebula', 'LUA JIT Fork and some Lua reworks', 'https://twitter.com/Nebula_Zorua', '7D40B2'], - ['Smokey', 'smokey', 'Sprite Atlas Support', 'https://twitter.com/Smokey_5_', '483D92'], - [''], - ["Funkin' Crew"], - ['ninjamuffin99', 'ninjamuffin99', "Programmer of Friday Night Funkin'", 'https://twitter.com/ninja_muffin99', 'CF2D2D'], - ['PhantomArcade', 'phantomarcade', "Animator of Friday Night Funkin'", 'https://twitter.com/PhantomArcade3K', 'FADC45'], - ['evilsk8r', 'evilsk8r', "Artist of Friday Night Funkin'", 'https://twitter.com/evilsk8r', '5ABD4B'], - ['kawaisprite', 'kawaisprite', "Composer of Friday Night Funkin'", 'https://twitter.com/kawaisprite', '378FC7'] - ]; - - for(i in pisspoop){ - creditsStuff.push(i); - } - - for (i in 0...creditsStuff.length) - { - var isSelectable:Bool = !unselectableCheck(i); - var optionText:Alphabet = new Alphabet(FlxG.width / 2, 300, creditsStuff[i][0], !isSelectable); - optionText.isMenuItem = true; - optionText.targetY = i; - optionText.changeX = false; - optionText.snapToPosition(); - grpOptions.add(optionText); - - if(isSelectable) { - if(creditsStuff[i][5] != null) - { - Paths.currentModDirectory = creditsStuff[i][5]; - } - - var icon:AttachedSprite = new AttachedSprite('credits/' + creditsStuff[i][1]); - icon.xAdd = optionText.width + 10; - icon.sprTracker = optionText; - - // using a FlxGroup is too much fuss! - iconArray.push(icon); - add(icon); - Paths.currentModDirectory = ''; - - if(curSelected == -1) curSelected = i; - } - else optionText.alignment = CENTERED; - } - - descBox = new AttachedSprite(); - descBox.makeGraphic(1, 1, FlxColor.BLACK); - descBox.xAdd = -10; - descBox.yAdd = -10; - descBox.alphaMult = 0.6; - descBox.alpha = 0.6; - add(descBox); - - descText = new FlxText(50, FlxG.height + offsetThing - 25, 1180, "", 32); - descText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER/*, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK*/); - descText.scrollFactor.set(); - //descText.borderSize = 2.4; - descBox.sprTracker = descText; - add(descText); - - bg.color = getCurrentBGColor(); - intendedColor = bg.color; - changeSelection(); - - #if android - addVirtualPad(UP_DOWN, A_B); - #end - - super.create(); - } - - var quitting:Bool = false; - var holdTime:Float = 0; - override function update(elapsed:Float) - { - if (FlxG.sound.music.volume < 0.7) - { - FlxG.sound.music.volume += 0.5 * FlxG.elapsed; - } - - if(!quitting) - { - if(creditsStuff.length > 1) - { - var shiftMult:Int = 1; - if(FlxG.keys.pressed.SHIFT) shiftMult = 3; - - var upP = controls.UI_UP_P; - var downP = controls.UI_DOWN_P; - - if (upP) - { - changeSelection(-shiftMult); - holdTime = 0; - } - if (downP) - { - changeSelection(shiftMult); - holdTime = 0; - } - - if(controls.UI_DOWN || controls.UI_UP) - { - var checkLastHold:Int = Math.floor((holdTime - 0.5) * 10); - holdTime += elapsed; - var checkNewHold:Int = Math.floor((holdTime - 0.5) * 10); - - if(holdTime > 0.5 && checkNewHold - checkLastHold > 0) - { - changeSelection((checkNewHold - checkLastHold) * (controls.UI_UP ? -shiftMult : shiftMult)); - } - } - } - - if(controls.ACCEPT && (creditsStuff[curSelected][3] == null || creditsStuff[curSelected][3].length > 4)) { - CoolUtil.browserLoad(creditsStuff[curSelected][3]); - } - if (controls.BACK) - { - if(colorTween != null) { - colorTween.cancel(); - } - FlxG.sound.play(Paths.sound('cancelMenu')); - MusicBeatState.switchState(new MainMenuState()); - quitting = true; - } - } - - for (item in grpOptions.members) - { - if(!item.bold) - { - var lerpVal:Float = CoolUtil.boundTo(elapsed * 12, 0, 1); - if(item.targetY == 0) - { - var lastX:Float = item.x; - item.screenCenter(X); - item.x = FlxMath.lerp(lastX, item.x - 70, lerpVal); - } - else - { - item.x = FlxMath.lerp(item.x, 200 + -40 * Math.abs(item.targetY), lerpVal); - } - } - } - super.update(elapsed); - } - - var moveTween:FlxTween = null; - function changeSelection(change:Int = 0) - { - FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); - do { - curSelected += change; - if (curSelected < 0) - curSelected = creditsStuff.length - 1; - if (curSelected >= creditsStuff.length) - curSelected = 0; - } while(unselectableCheck(curSelected)); - - var newColor:Int = getCurrentBGColor(); - if(newColor != intendedColor) { - if(colorTween != null) { - colorTween.cancel(); - } - intendedColor = newColor; - colorTween = FlxTween.color(bg, 1, bg.color, intendedColor, { - onComplete: function(twn:FlxTween) { - colorTween = null; - } - }); - } - - var bullShit:Int = 0; - - for (item in grpOptions.members) - { - item.targetY = bullShit - curSelected; - bullShit++; - - if(!unselectableCheck(bullShit-1)) { - item.alpha = 0.6; - if (item.targetY == 0) { - item.alpha = 1; - } - } - } - - descText.text = creditsStuff[curSelected][2]; - descText.y = FlxG.height - descText.height + offsetThing - 60; - - if(moveTween != null) moveTween.cancel(); - moveTween = FlxTween.tween(descText, {y : descText.y + 75}, 0.25, {ease: FlxEase.sineOut}); - - descBox.setGraphicSize(Std.int(descText.width + 20), Std.int(descText.height + 25)); - descBox.updateHitbox(); - } - - #if MODS_ALLOWED - private var modsAdded:Array = []; - function pushModCreditsToList(folder:String) - { - if(modsAdded.contains(folder)) return; - - var creditsFile:String = null; - if(folder != null && folder.trim().length > 0) creditsFile = Paths.mods(folder + '/data/credits.txt'); - else creditsFile = Paths.mods('data/credits.txt'); - - if (FileSystem.exists(creditsFile)) - { - var firstarray:Array = File.getContent(creditsFile).split('\n'); - for(i in firstarray) - { - var arr:Array = i.replace('\\n', '\n').split("::"); - if(arr.length >= 5) arr.push(folder); - creditsStuff.push(arr); - } - creditsStuff.push(['']); - } - modsAdded.push(folder); - } - #end - - function getCurrentBGColor() { - var bgColor:String = creditsStuff[curSelected][4]; - if(!bgColor.startsWith('0x')) { - bgColor = '0xFF' + bgColor; - } - return Std.parseInt(bgColor); - } - - private function unselectableCheck(num:Int):Bool { - return creditsStuff[num].length <= 1; - } +package; + +#if desktop +import Discord.DiscordClient; +#end +import flash.text.TextField; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import flixel.tweens.FlxTween; +import flixel.tweens.FlxEase; +#if MODS_ALLOWED +import sys.FileSystem; +import sys.io.File; +#end +import lime.utils.Assets; + +using StringTools; + +class CreditsState extends MusicBeatState +{ + var curSelected:Int = -1; + + private var grpOptions:FlxTypedGroup; + private var iconArray:Array = []; + private var creditsStuff:Array> = []; + + var bg:FlxSprite; + var descText:FlxText; + var intendedColor:Int; + var colorTween:FlxTween; + var descBox:AttachedSprite; + + var offsetThing:Float = -75; + + override function create() + { + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); + + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Menus", null); + #end + + persistentUpdate = true; + bg = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + add(bg); + bg.screenCenter(); + + grpOptions = new FlxTypedGroup(); + add(grpOptions); + + #if MODS_ALLOWED + var path:String = 'modsList.txt'; + if(FileSystem.exists(path)) + { + var leMods:Array = CoolUtil.coolTextFile(path); + for (i in 0...leMods.length) + { + if(leMods.length > 1 && leMods[0].length > 0) { + var modSplit:Array = leMods[i].split('|'); + if(!Paths.ignoreModFolders.contains(modSplit[0].toLowerCase()) && !modsAdded.contains(modSplit[0])) + { + if(modSplit[1] == '1') + pushModCreditsToList(modSplit[0]); + else + modsAdded.push(modSplit[0]); + } + } + } + } + + var arrayOfFolders:Array = Paths.getModDirectories(); + arrayOfFolders.push(''); + for (folder in arrayOfFolders) + { + pushModCreditsToList(folder); + } + #end + + var pisspoop:Array> = [ //Name - Icon name - Description - Link - BG Color + ['JS Engine People'], + ['Jordan Santiago', 'jor', 'Coded everything into JS Engine', 'https://twitter.com/JordansTweetsYT', 'FF9300'], + ['Stefan2008', 'stef', "Granted permission to use the Results Screen code, and helped\nwith the Android version's development", 'https://www.youtube.com/channel/UC9Nwf21GbaEm_h0Ka9gxZjQ', '800080'], + [''], + ['Psych Engine Team'], + ['Shadow Mario', 'shadowmario', 'Main Programmer of Psych Engine', 'https://twitter.com/Shadow_Mario_', '444444'], + ['RiverOaken', 'river', 'Main Artist/Animator of Psych Engine', 'https://twitter.com/RiverOaken', 'B42F71'], + ['shubs', 'shubs', 'Additional Programmer of Psych Engine', 'https://twitter.com/yoshubs', '5E99DF'], + [''], + ['Former Engine Members'], + ['bb-panzu', 'bb', 'Ex-Programmer of Psych Engine', 'https://twitter.com/bbsub3', '3E813A'], + [''], + ['Engine Contributors'], + ['iFlicky', 'flicky', 'Composer of Psync and Tea Time\nMade the Dialogue Sounds', 'https://twitter.com/flicky_i', '9E29CF'], + ['SqirraRNG', 'sqirra', 'Crash Handler and Base code for\nChart Editor\'s Waveform', 'https://twitter.com/gedehari', 'E1843A'], + ['EliteMasterEric', 'mastereric', 'Runtime Shaders support', 'https://twitter.com/EliteMasterEric', 'FFBD40'], + ['PolybiusProxy', 'proxy', '.MP4 Video Loader Library (hxCodec)', 'https://twitter.com/polybiusproxy', 'DCD294'], + ['KadeDev', 'kade', 'Fixed some cool stuff on Chart Editor\nand other PRs', 'https://twitter.com/kade0912', '64A250'], + ['Keoiki', 'keoiki', 'Note Splash Animations', 'https://twitter.com/Keoiki_', 'D2D2D2'], + ['Nebula the Zorua', 'nebula', 'LUA JIT Fork and some Lua reworks', 'https://twitter.com/Nebula_Zorua', '7D40B2'], + ['Smokey', 'smokey', 'Sprite Atlas Support', 'https://twitter.com/Smokey_5_', '483D92'], + [''], + ["Funkin' Crew"], + ['ninjamuffin99', 'ninjamuffin99', "Programmer of Friday Night Funkin'", 'https://twitter.com/ninja_muffin99', 'CF2D2D'], + ['PhantomArcade', 'phantomarcade', "Animator of Friday Night Funkin'", 'https://twitter.com/PhantomArcade3K', 'FADC45'], + ['evilsk8r', 'evilsk8r', "Artist of Friday Night Funkin'", 'https://twitter.com/evilsk8r', '5ABD4B'], + ['kawaisprite', 'kawaisprite', "Composer of Friday Night Funkin'", 'https://twitter.com/kawaisprite', '378FC7'] + ]; + + for(i in pisspoop){ + creditsStuff.push(i); + } + + for (i in 0...creditsStuff.length) + { + var isSelectable:Bool = !unselectableCheck(i); + var optionText:Alphabet = new Alphabet(FlxG.width / 2, 300, creditsStuff[i][0], !isSelectable); + optionText.isMenuItem = true; + optionText.targetY = i; + optionText.changeX = false; + optionText.snapToPosition(); + grpOptions.add(optionText); + + if(isSelectable) { + if(creditsStuff[i][5] != null) + { + Paths.currentModDirectory = creditsStuff[i][5]; + } + + var icon:AttachedSprite = new AttachedSprite('credits/' + creditsStuff[i][1]); + icon.xAdd = optionText.width + 10; + icon.sprTracker = optionText; + + // using a FlxGroup is too much fuss! + iconArray.push(icon); + add(icon); + Paths.currentModDirectory = ''; + + if(curSelected == -1) curSelected = i; + } + else optionText.alignment = CENTERED; + } + + descBox = new AttachedSprite(); + descBox.makeGraphic(1, 1, FlxColor.BLACK); + descBox.xAdd = -10; + descBox.yAdd = -10; + descBox.alphaMult = 0.6; + descBox.alpha = 0.6; + add(descBox); + + descText = new FlxText(50, FlxG.height + offsetThing - 25, 1180, "", 32); + descText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER/*, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK*/); + descText.scrollFactor.set(); + //descText.borderSize = 2.4; + descBox.sprTracker = descText; + add(descText); + + bg.color = getCurrentBGColor(); + intendedColor = bg.color; + changeSelection(); + + #if android + addVirtualPad(UP_DOWN, A_B); + #end + + super.create(); + } + + var quitting:Bool = false; + var holdTime:Float = 0; + override function update(elapsed:Float) + { + if (FlxG.sound.music.volume < 0.7) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + + if(!quitting) + { + if(creditsStuff.length > 1) + { + var shiftMult:Int = 1; + if(FlxG.keys.pressed.SHIFT) shiftMult = 3; + + var upP = controls.UI_UP_P; + var downP = controls.UI_DOWN_P; + + if (upP) + { + changeSelection(-shiftMult); + holdTime = 0; + } + if (downP) + { + changeSelection(shiftMult); + holdTime = 0; + } + + if(controls.UI_DOWN || controls.UI_UP) + { + var checkLastHold:Int = Math.floor((holdTime - 0.5) * 10); + holdTime += elapsed; + var checkNewHold:Int = Math.floor((holdTime - 0.5) * 10); + + if(holdTime > 0.5 && checkNewHold - checkLastHold > 0) + { + changeSelection((checkNewHold - checkLastHold) * (controls.UI_UP ? -shiftMult : shiftMult)); + } + } + } + + if(controls.ACCEPT && (creditsStuff[curSelected][3] == null || creditsStuff[curSelected][3].length > 4)) { + CoolUtil.browserLoad(creditsStuff[curSelected][3]); + } + if (controls.BACK) + { + if(colorTween != null) { + colorTween.cancel(); + } + FlxG.sound.play(Paths.sound('cancelMenu')); + MusicBeatState.switchState(new MainMenuState()); + quitting = true; + } + } + + for (item in grpOptions.members) + { + if(!item.bold) + { + var lerpVal:Float = CoolUtil.boundTo(elapsed * 12, 0, 1); + if(item.targetY == 0) + { + var lastX:Float = item.x; + item.screenCenter(X); + item.x = FlxMath.lerp(lastX, item.x - 70, lerpVal); + } + else + { + item.x = FlxMath.lerp(item.x, 200 + -40 * Math.abs(item.targetY), lerpVal); + } + } + } + super.update(elapsed); + } + + var moveTween:FlxTween = null; + function changeSelection(change:Int = 0) + { + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + do { + curSelected += change; + if (curSelected < 0) + curSelected = creditsStuff.length - 1; + if (curSelected >= creditsStuff.length) + curSelected = 0; + } while(unselectableCheck(curSelected)); + + var newColor:Int = getCurrentBGColor(); + if(newColor != intendedColor) { + if(colorTween != null) { + colorTween.cancel(); + } + intendedColor = newColor; + colorTween = FlxTween.color(bg, 1, bg.color, intendedColor, { + onComplete: function(twn:FlxTween) { + colorTween = null; + } + }); + } + + var bullShit:Int = 0; + + for (item in grpOptions.members) + { + item.targetY = bullShit - curSelected; + bullShit++; + + if(!unselectableCheck(bullShit-1)) { + item.alpha = 0.6; + if (item.targetY == 0) { + item.alpha = 1; + } + } + } + + descText.text = creditsStuff[curSelected][2]; + descText.y = FlxG.height - descText.height + offsetThing - 60; + + if(moveTween != null) moveTween.cancel(); + moveTween = FlxTween.tween(descText, {y : descText.y + 75}, 0.25, {ease: FlxEase.sineOut}); + + descBox.setGraphicSize(Std.int(descText.width + 20), Std.int(descText.height + 25)); + descBox.updateHitbox(); + } + + #if MODS_ALLOWED + private var modsAdded:Array = []; + function pushModCreditsToList(folder:String) + { + if(modsAdded.contains(folder)) return; + + var creditsFile:String = null; + if(folder != null && folder.trim().length > 0) creditsFile = Paths.mods(folder + '/data/credits.txt'); + else creditsFile = Paths.mods('data/credits.txt'); + + if (FileSystem.exists(creditsFile)) + { + var firstarray:Array = File.getContent(creditsFile).split('\n'); + for(i in firstarray) + { + var arr:Array = i.replace('\\n', '\n').split("::"); + if(arr.length >= 5) arr.push(folder); + creditsStuff.push(arr); + } + creditsStuff.push(['']); + } + modsAdded.push(folder); + } + #end + + function getCurrentBGColor() { + var bgColor:String = creditsStuff[curSelected][4]; + if(!bgColor.startsWith('0x')) { + bgColor = '0xFF' + bgColor; + } + return Std.parseInt(bgColor); + } + + private function unselectableCheck(num:Int):Bool { + return creditsStuff[num].length <= 1; + } } \ No newline at end of file diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 903898c72a2..dcafcb7772f 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -1,727 +1,727 @@ -package; - -import openfl.display.Tile; -#if desktop -import Discord.DiscordClient; -#end -import editors.ChartingState; -import flash.text.TextField; -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.addons.display.FlxGridOverlay; -import flixel.addons.transition.FlxTransitionableState; -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.math.FlxMath; -import flixel.text.FlxText; -import flixel.util.FlxColor; -import flixel.tweens.FlxTween; -import lime.utils.Assets; -import flixel.system.FlxSound; -import flixel.tweens.FlxEase; -import flixel.tweens.FlxTween; -import openfl.utils.Assets as OpenFlAssets; -import flixel.util.FlxStringUtil; //for formatting the note count -import WeekData; -#if MODS_ALLOWED -import sys.FileSystem; -#end - -using StringTools; - -class FreeplayState extends MusicBeatState -{ - var songs:Array = []; - - var selector:FlxText; - private static var curSelected:Int = 0; - var curDifficulty:Int = -1; - private static var lastDifficultyName:String = ''; - - var scoreBG:FlxSprite; - var scoreText:FlxText; - var diffText:FlxText; - var lerpScore:Float = 0; - var lerpRating:Float = 0; - var intendedScore:Float = 0; - var intendedRating:Float = 0; - var requiredRamLoad:Float = 0; - var noteCount:Float = 0; - - private var grpSongs:FlxTypedGroup; - - public static var curPlaying:Bool = false; - - var lerpSelected:Float = 0; - - private var iconArray:Array = []; - - var bg:FlxSprite; - var intendedColor:Int; - var colorTween:FlxTween; - var missingTextBG:FlxSprite; - var missingText:FlxText; - - override function create() - { - Paths.clearStoredMemory(); - Paths.clearUnusedMemory(); - - persistentUpdate = true; - PlayState.isStoryMode = false; - WeekData.reloadWeekFiles(false); - - #if desktop - // Updating Discord Rich Presence - DiscordClient.changePresence("In the Menus", null); - #end - - for (i in 0...WeekData.weeksList.length) { - if(weekIsLocked(WeekData.weeksList[i])) continue; - - var leWeek:WeekData = WeekData.weeksLoaded.get(WeekData.weeksList[i]); - var leSongs:Array = []; - var leChars:Array = []; - - for (j in 0...leWeek.songs.length) - { - leSongs.push(leWeek.songs[j][0]); - leChars.push(leWeek.songs[j][1]); - } - - WeekData.setDirectoryFromWeek(leWeek); - for (song in leWeek.songs) - { - var colors:Array = song[2]; - if(colors == null || colors.length < 3) - { - colors = [146, 113, 253]; - } - addSong(song[0], i, song[1], FlxColor.fromRGB(colors[0], colors[1], colors[2])); - } - } - WeekData.loadTheFirstEnabledMod(); - - /* //KIND OF BROKEN NOW AND ALSO PRETTY USELESS// - - var initSonglist = CoolUtil.coolTextFile(Paths.txt('freeplaySonglist')); - for (i in 0...initSonglist.length) - { - if(initSonglist[i] != null && initSonglist[i].length > 0) { - var songArray:Array = initSonglist[i].split(":"); - addSong(songArray[0], 0, songArray[1], Std.parseInt(songArray[2])); - } - }*/ - - #if PRELOAD_ALL - if (!curPlaying) Conductor.changeBPM(TitleState.titleJSON.bpm); - #end - - bg = new FlxSprite().loadGraphic(Paths.image('menuDesat')); - bg.antialiasing = ClientPrefs.globalAntialiasing; - add(bg); - bg.screenCenter(); - - grpSongs = new FlxTypedGroup(); - add(grpSongs); - - for (i in 0...songs.length) - { - var songText:Alphabet = new Alphabet(90, 320, songs[i].songName, true); - songText.isMenuItem = true; - songText.targetY = i - curSelected; - grpSongs.add(songText); - - var maxWidth = 980; - if (songText.width > maxWidth) - { - songText.scaleX = maxWidth / songText.width; - } - songText.snapToPosition(); - - Paths.currentModDirectory = songs[i].folder; - var icon:HealthIcon = new HealthIcon(songs[i].songCharacter); - icon.sprTracker = songText; - - // using a FlxGroup is too much fuss! - iconArray.push(icon); - add(icon); - - // songText.x += 40; - // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! - // songText.screenCenter(X); - } - WeekData.setDirectoryFromWeek(); - - scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32); - scoreText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT); - - scoreBG = new FlxSprite(scoreText.x - 6, 0).makeGraphic(1, 66, 0xFF000000); - scoreBG.alpha = 0.6; - add(scoreBG); - - diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24); - diffText.font = scoreText.font; - add(diffText); - - add(scoreText); - - missingTextBG = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - missingTextBG.alpha = 0.6; - missingTextBG.visible = false; - add(missingTextBG); - - missingText = new FlxText(50, 0, FlxG.width - 100, '', 24); - missingText.setFormat(Paths.font("vcr.ttf"), 24, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - missingText.scrollFactor.set(); - missingText.visible = false; - add(missingText); - - if(curSelected >= songs.length) curSelected = 0; - bg.color = songs[curSelected].color; - intendedColor = bg.color; - - if(lastDifficultyName == '') - { - lastDifficultyName = CoolUtil.defaultDifficulty; - } - curDifficulty = Math.round(Math.max(0, CoolUtil.defaultDifficulties.indexOf(lastDifficultyName))); - - if(curPlaying) - { - iconArray[instPlaying].canBounce = true; - } - - changeSelection(); - changeDiff(); - - var swag:Alphabet = new Alphabet(1, 0, "swag"); - - // JUST DOIN THIS SHIT FOR TESTING!!! - /* - var md:String = Markdown.markdownToHtml(Assets.getText('CHANGELOG.md')); - - var texFel:TextField = new TextField(); - texFel.width = FlxG.width; - texFel.height = FlxG.height; - // texFel. - texFel.htmlText = md; - - FlxG.stage.addChild(texFel); - - // scoreText.textField.htmlText = md; - - trace(md); - */ - - var textBG:FlxSprite = new FlxSprite(0, FlxG.height - 26).makeGraphic(FlxG.width, 26, 0xFF000000); - textBG.alpha = 0.6; - add(textBG); - - #if PRELOAD_ALL - #if android - var leText:String = "Press X to listen to the Song / Press C to open the Gameplay Changers Menu / Press Y to Reset your Score and Accuracy."; - var size:Int = 16; - #else - var leText:String = "Press SPACE to listen to the Song / Press CTRL to open the Gameplay Changers Menu / Press RESET to Reset your Score and Accuracy."; - var size:Int = 16; - #end - #else - var leText:String = "Press C to open the Gameplay Changers Menu / Press Y to Reset your Score and Accuracy."; - var size:Int = 18; - #end - var text:FlxText = new FlxText(textBG.x, textBG.y + 4, FlxG.width, leText, size); - text.setFormat(Paths.font("vcr.ttf"), size, FlxColor.WHITE, RIGHT); - text.scrollFactor.set(); - add(text); - - #if android - addVirtualPad(LEFT_FULL, A_B_C_X_Y_Z); - #end - - super.create(); - } - - override function closeSubState() { - changeSelection(0, false); - persistentUpdate = true; - super.closeSubState(); - } - - public function addSong(songName:String, weekNum:Int, songCharacter:String, color:Int) - { - songs.push(new SongMetadata(songName, weekNum, songCharacter, color)); - } - - function weekIsLocked(name:String):Bool { - var leWeek:WeekData = WeekData.weeksLoaded.get(name); - return (!leWeek.startUnlocked && leWeek.weekBefore.length > 0 && (!StoryMenuState.weekCompleted.exists(leWeek.weekBefore) || !StoryMenuState.weekCompleted.get(leWeek.weekBefore))); - } - - /*public function addWeek(songs:Array, weekNum:Int, weekColor:Int, ?songCharacters:Array) - { - if (songCharacters == null) - songCharacters = ['bf']; - - var num:Int = 0; - for (song in songs) - { - addSong(song, weekNum, songCharacters[num]); - this.songs[this.songs.length-1].color = weekColor; - - if (songCharacters.length != 1) - num++; - } - }*/ - - public static var instPlaying:Int = -1; - public static var vocals:FlxSound = null; - var holdTime:Float = 0; - override function update(elapsed:Float) - { - if (FlxG.sound.music != null) - Conductor.songPosition = FlxG.sound.music.time; - - if (FlxG.sound.music.volume < 0.7) - { - FlxG.sound.music.volume += 0.5 * FlxG.elapsed; - } - - for (i in 0...iconArray.length) - { - iconArray[i].scale.set(FlxMath.lerp(iconArray[i].scale.x, 1, elapsed * 9), - FlxMath.lerp(iconArray[i].scale.y, 1, elapsed * 9)); - } - - lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, CoolUtil.boundTo(elapsed * 24, 0, 1))); - lerpRating = FlxMath.lerp(lerpRating, intendedRating, CoolUtil.boundTo(elapsed * 12, 0, 1)); - - if (Math.abs(lerpScore - intendedScore) <= 10) - lerpScore = intendedScore; - if (Math.abs(lerpRating - intendedRating) <= 0.01) - lerpRating = intendedRating; - - var ratingSplit:Array = Std.string(Highscore.floorDecimal(lerpRating * 100, 2)).split('.'); - if(ratingSplit.length < 2) { //No decimals, add an empty space - ratingSplit.push(''); - } - - while(ratingSplit[1].length < 2) { //Less than 2 decimals in it, add decimals then - ratingSplit[1] += '0'; - } - - scoreText.text = 'PERSONAL BEST: ' + lerpScore + ' (' + ratingSplit.join('.') + '%)'; - positionHighscore(); - - var upP = controls.UI_UP_P; - var downP = controls.UI_DOWN_P; - var accepted = controls.ACCEPT; - var space = FlxG.keys.justPressed.SPACE #if android || virtualPad.buttonX.justPressed #end; - var ctrl = FlxG.keys.justPressed.CONTROL #if android || virtualPad.buttonC.justPressed #end; - - var shiftMult:Int = 1; - if (FlxG.keys.pressed.SHIFT #if android || virtualPad.buttonZ.pressed #end) shiftMult = 3; - - if(songs.length > 1) - { - if (upP) - { - changeSelection(-shiftMult); - holdTime = 0; - } - if (downP) - { - changeSelection(shiftMult); - holdTime = 0; - } - - if(controls.UI_DOWN || controls.UI_UP) - { - var checkLastHold:Int = Math.floor((holdTime - 0.5) * 10); - holdTime += elapsed; - var checkNewHold:Int = Math.floor((holdTime - 0.5) * 10); - if(holdTime > 0.5 && checkNewHold - checkLastHold > 0) - { - changeSelection((checkNewHold - checkLastHold) * (controls.UI_UP ? -shiftMult : shiftMult)); - changeDiff(); - } - } - - if(FlxG.mouse.wheel != 0) - { - FlxG.sound.play(Paths.sound('scrollMenu'), 0.2); - changeSelection(-shiftMult * FlxG.mouse.wheel, false); - changeDiff(); - } - } - - if (controls.UI_LEFT_P) - changeDiff(-1); - else if (controls.UI_RIGHT_P) - changeDiff(1); - else if (upP || downP) changeDiff(); - - if (controls.BACK) - { - persistentUpdate = false; - if(colorTween != null) { - colorTween.cancel(); - } - FlxG.sound.play(Paths.sound('cancelMenu')); - MusicBeatState.switchState(new MainMenuState()); - } - - if(ctrl) - { - #if android - removeVirtualPad(); - #end - persistentUpdate = false; - openSubState(new GameplayChangersSubstate()); - } - else if(space) - { - requiredRamLoad = 0; - noteCount = 0; - function playSong() { - #if PRELOAD_ALL - destroyFreeplayVocals(); - FlxG.sound.music.volume = 0; - Paths.currentModDirectory = songs[curSelected].folder; - var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); - PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName.toLowerCase()); - if (PlayState.SONG.needsVoices) - vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song)); - else - vocals = new FlxSound(); - - FlxG.sound.list.add(vocals); - FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 0.7); - vocals.play(); - vocals.persist = true; - vocals.looped = true; - vocals.volume = 0.7; - instPlaying = curSelected; - Conductor.changeBPM(PlayState.SONG.bpm); - for (i in 0...iconArray.length) - iconArray[i].canBounce = false; - iconArray[instPlaying].canBounce = true; - curPlaying = true; - #end - - if (FlxG.keys.pressed.SHIFT #if android || virtualPad.buttonZ.pressed #end) { - for (section in PlayState.SONG.notes) { - noteCount += section.sectionNotes.length; - requiredRamLoad += 72872 * section.sectionNotes.length; - } - CoolUtil.coolError("There are " + FlxStringUtil.formatMoney(noteCount, false) + " notes in this chart!\nWith Show Notes turned on, you'd need " + formatCompactNumber(requiredRamLoad / 2) + " of ram to load this.", "JS Engine Chart Diagnosis"); - } - } - function songJsonPopup() { //you pressed space, but the song's ogg files don't exist - var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); - trace(poop + '\'s .ogg does not exist!'); - FlxG.sound.play(Paths.sound('invalidJSON')); - FlxG.camera.shake(0.05, 0.05); - var funnyText = new FlxText(12, FlxG.height - 24, 0, "Invalid Song!"); - funnyText.scrollFactor.set(); - funnyText.screenCenter(); - funnyText.x = 5; - funnyText.y = FlxG.height/2 - 64; - funnyText.setFormat("vcr.ttf", 64, FlxColor.RED, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - add(funnyText); - FlxTween.tween(funnyText, {alpha: 0}, 0.9, { - onComplete: _ -> { - remove(funnyText, true); - funnyText.destroy(); - } - }); - } - var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); - var songLowercase:String = Paths.formatToSongPath(songs[curSelected].songName); - #if desktop - if(instPlaying != curSelected) - { - if(sys.FileSystem.exists(Paths.inst(songLowercase + '/' + poop)) || sys.FileSystem.exists(Paths.json(songLowercase + '/' + poop)) || sys.FileSystem.exists(Paths.modsJson(songLowercase + '/' + poop))) - playSong(); - else - songJsonPopup(); - } - #else - if(instPlaying != curSelected) - { - if(OpenFlAssets.exists(Paths.inst(songLowercase + '/' + poop)) || OpenFlAssets.exists(Paths.json(songLowercase + '/' + poop))) - playSong(); - else - songJsonPopup(); - } - #end - } - - else if (accepted) - { - - persistentUpdate = false; - var songLowercase:String = Paths.formatToSongPath(songs[curSelected].songName); - var poop:String = Highscore.formatSong(songLowercase, curDifficulty); - /*#if MODS_ALLOWED - if(!sys.FileSystem.exists(Paths.modsJson(songLowercase + '/' + poop)) && !sys.FileSystem.exists(Paths.json(songLowercase + '/' + poop))) { - #else - if(!OpenFlAssets.exists(Paths.json(songLowercase + '/' + poop))) { - #end - poop = songLowercase; - curDifficulty = 1; - trace('Couldnt find file'); - }*/ - trace(poop); - - if(sys.FileSystem.exists(Paths.modsJson(songLowercase + '/' + poop)) || sys.FileSystem.exists(Paths.json(songLowercase + '/' + poop))) {//fix an issue where any song in the mods folder would return an error even if both the json and song files existed - PlayState.SONG = Song.loadFromJson(poop, songLowercase); - PlayState.isStoryMode = false; - PlayState.storyDifficulty = curDifficulty; - - trace('CURRENT WEEK: ' + WeekData.getWeekFileName()); - if(colorTween != null) { - colorTween.cancel(); - } - - curPlaying = false; - - if (FlxG.keys.pressed.SHIFT #if android || virtualPad.buttonZ.pressed #end) { - LoadingState.loadAndSwitchState(new ChartingState()); - }else{ - LoadingState.loadAndSwitchState(new PlayState()); - } - - FlxG.sound.music.volume = 0; - - destroyFreeplayVocals(); - - } else { - if(sys.FileSystem.exists(Paths.inst(poop + '/' + poop)) && !sys.FileSystem.exists(Paths.json(poop + '/' + poop))) { //the json doesn't exist, but the song files do, or you put a typo in the name - CoolUtil.coolError("The JSON's name does not match with " + poop + "!\nTry making them match.", "JS Engine Anti-Crash Tool"); - } else if(sys.FileSystem.exists(Paths.json(poop + '/' + poop)) && !sys.FileSystem.exists(Paths.inst(poop + '/' + poop))) {//the json exists, but the song files don't - CoolUtil.coolError("Your song seems to not have an Inst.ogg, check the folder name in 'songs'!", "JS Engine Anti-Crash Tool"); - } else if(!sys.FileSystem.exists(Paths.json(poop + '/' + poop)) && !sys.FileSystem.exists(Paths.inst(poop + '/' + poop))) { //neither the json nor the song files actually exist - CoolUtil.coolError("It appears that " + poop + " doesn't actually have a JSON, nor does it actually have voices/instrumental files!\nMaybe try fixing its name in weeks/" + WeekData.getWeekFileName() + "?", "JS Engine Anti-Crash Tool"); - } - } - } - else if (controls.RESET #if android || virtualPad.buttonY.justPressed #end) { - #if android - removeVirtualPad(); - #end - persistentUpdate = false; - openSubState(new ResetScoreSubState(songs[curSelected].songName, curDifficulty, songs[curSelected].songCharacter)); - FlxG.sound.play(Paths.sound('scrollMenu')); - } - super.update(elapsed); - } - - public static function destroyFreeplayVocals() { - if(vocals != null) { - vocals.stop(); - vocals.destroy(); - } - vocals = null; - } - - function changeDiff(change:Int = 0) - { - curDifficulty += change; - - if (curDifficulty < 0) - curDifficulty = CoolUtil.difficulties.length-1; - if (curDifficulty >= CoolUtil.difficulties.length) - curDifficulty = 0; - - lastDifficultyName = CoolUtil.difficulties[curDifficulty]; - - #if !switch - intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); - intendedRating = Highscore.getRating(songs[curSelected].songName, curDifficulty); - #end - - PlayState.storyDifficulty = curDifficulty; - diffText.text = '< ' + CoolUtil.difficultyString() + ' >'; - positionHighscore(); - } - - public static function formatCompactNumber(number:Float):String //this entire function is ai generated LMAO - { - var suffixes:Array = [' bytes', ' KB', ' MB', ' GB', 'TB']; - var magnitude:Int = 0; - var num:Float = number; - - while (num >= 1000.0 && magnitude < suffixes.length - 1) - { - num /= 1000.0; - magnitude++; - } - - // Use the floor value for the compact representation - var compactValue:Float = Math.floor(num * 100) / 100; - if (compactValue <= 0.001) { - return "0"; //Return 0 if compactValue = null - } else { - return compactValue + (magnitude == 0 ? "" : "") + suffixes[magnitude]; - } - } - - function changeSelection(change:Int = 0, playSound:Bool = true) - { - if(playSound) FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); - - curSelected += change; - - if (curSelected < 0) - curSelected = songs.length - 1; - if (curSelected >= songs.length) - curSelected = 0; - - var newColor:Int = songs[curSelected].color; - if(newColor != intendedColor) { - if(colorTween != null) { - colorTween.cancel(); - } - intendedColor = newColor; - colorTween = FlxTween.color(bg, 1, bg.color, intendedColor, { - onComplete: function(twn:FlxTween) { - colorTween = null; - } - }); - } - - // selector.y = (70 * curSelected) + 30; - - #if !switch - intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); - intendedRating = Highscore.getRating(songs[curSelected].songName, curDifficulty); - #end - - var bullShit:Int = 0; - - for (i in 0...iconArray.length) - { - iconArray[i].alpha = 0.6; - } - - iconArray[curSelected].alpha = 1; - - for (item in grpSongs.members) - { - item.targetY = bullShit - curSelected; - bullShit++; - - item.alpha = 0.6; - // item.setGraphicSize(Std.int(item.width * 0.8)); - - if (item.targetY == 0) - { - item.alpha = 1; - // item.setGraphicSize(Std.int(item.width)); - } - } - - Paths.currentModDirectory = songs[curSelected].folder; - PlayState.storyWeek = songs[curSelected].week; - - CoolUtil.difficulties = CoolUtil.defaultDifficulties.copy(); - var diffStr:String = WeekData.getCurrentWeek().difficulties; - if(diffStr != null) diffStr = diffStr.trim(); //Fuck you HTML5 - - if(diffStr != null && diffStr.length > 0) - { - var diffs:Array = diffStr.split(','); - var i:Int = diffs.length - 1; - while (i > 0) - { - if(diffs[i] != null) - { - diffs[i] = diffs[i].trim(); - if(diffs[i].length < 1) diffs.remove(diffs[i]); - } - --i; - } - - if(diffs.length > 0 && diffs[0].length > 0) - { - CoolUtil.difficulties = diffs; - } - } - - if(CoolUtil.difficulties.contains(CoolUtil.defaultDifficulty)) - { - curDifficulty = Math.round(Math.max(0, CoolUtil.defaultDifficulties.indexOf(CoolUtil.defaultDifficulty))); - } - else - { - curDifficulty = 0; - } - - var newPos:Int = CoolUtil.difficulties.indexOf(lastDifficultyName); - //trace('Pos of ' + lastDifficultyName + ' is ' + newPos); - if(newPos > -1) - { - curDifficulty = newPos; - } - } - - private function positionHighscore() { - scoreText.x = FlxG.width - scoreText.width - 6; - - scoreBG.scale.x = FlxG.width - scoreText.x + 6; - scoreBG.x = FlxG.width - (scoreBG.scale.x / 2); - diffText.x = Std.int(scoreBG.x + (scoreBG.width / 2)); - diffText.x -= diffText.width / 2; - } - override function beatHit() { - super.beatHit(); - - if (curPlaying) - iconArray[instPlaying].bounce(); - } - var _drawDistance:Int = 4; - var _lastVisibles:Array = []; - public function updateTexts(elapsed:Float = 0.0) - { - lerpSelected = FlxMath.lerp(lerpSelected, curSelected, FlxMath.bound(elapsed * 9.6, 0, 1)); - for (i in _lastVisibles) - { - grpSongs.members[i].visible = grpSongs.members[i].active = false; - iconArray[i].visible = iconArray[i].active = false; - } - _lastVisibles = []; - - var min:Int = Math.round(Math.max(0, Math.min(songs.length, lerpSelected - _drawDistance))); - var max:Int = Math.round(Math.max(0, Math.min(songs.length, lerpSelected + _drawDistance))); - for (i in min...max) - { - var item:Alphabet = grpSongs.members[i]; - item.visible = item.active = true; - item.x = ((item.targetY - lerpSelected) * item.distancePerItem.x) + item.startPosition.x; - item.y = ((item.targetY - lerpSelected) * 1.3 * item.distancePerItem.y) + item.startPosition.y; - - var icon:HealthIcon = iconArray[i]; - icon.visible = icon.active = true; - _lastVisibles.push(i); - } - } -} - -class SongMetadata -{ - public var songName:String = ""; - public var week:Int = 0; - public var songCharacter:String = ""; - public var color:Int = -7179779; - public var folder:String = ""; - - public function new(song:String, week:Int, songCharacter:String, color:Int) - { - this.songName = song; - this.week = week; - this.songCharacter = songCharacter; - this.color = color; - this.folder = Paths.currentModDirectory; - if(this.folder == null) this.folder = ''; - } +package; + +import openfl.display.Tile; +#if desktop +import Discord.DiscordClient; +#end +import editors.ChartingState; +import flash.text.TextField; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +import flixel.addons.transition.FlxTransitionableState; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import flixel.tweens.FlxTween; +import lime.utils.Assets; +import flixel.system.FlxSound; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import openfl.utils.Assets as OpenFlAssets; +import flixel.util.FlxStringUtil; //for formatting the note count +import WeekData; +#if MODS_ALLOWED +import sys.FileSystem; +#end + +using StringTools; + +class FreeplayState extends MusicBeatState +{ + var songs:Array = []; + + var selector:FlxText; + private static var curSelected:Int = 0; + var curDifficulty:Int = -1; + private static var lastDifficultyName:String = ''; + + var scoreBG:FlxSprite; + var scoreText:FlxText; + var diffText:FlxText; + var lerpScore:Float = 0; + var lerpRating:Float = 0; + var intendedScore:Float = 0; + var intendedRating:Float = 0; + var requiredRamLoad:Float = 0; + var noteCount:Float = 0; + + private var grpSongs:FlxTypedGroup; + + public static var curPlaying:Bool = false; + + var lerpSelected:Float = 0; + + private var iconArray:Array = []; + + var bg:FlxSprite; + var intendedColor:Int; + var colorTween:FlxTween; + var missingTextBG:FlxSprite; + var missingText:FlxText; + + override function create() + { + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); + + persistentUpdate = true; + PlayState.isStoryMode = false; + WeekData.reloadWeekFiles(false); + + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Menus", null); + #end + + for (i in 0...WeekData.weeksList.length) { + if(weekIsLocked(WeekData.weeksList[i])) continue; + + var leWeek:WeekData = WeekData.weeksLoaded.get(WeekData.weeksList[i]); + var leSongs:Array = []; + var leChars:Array = []; + + for (j in 0...leWeek.songs.length) + { + leSongs.push(leWeek.songs[j][0]); + leChars.push(leWeek.songs[j][1]); + } + + WeekData.setDirectoryFromWeek(leWeek); + for (song in leWeek.songs) + { + var colors:Array = song[2]; + if(colors == null || colors.length < 3) + { + colors = [146, 113, 253]; + } + addSong(song[0], i, song[1], FlxColor.fromRGB(colors[0], colors[1], colors[2])); + } + } + WeekData.loadTheFirstEnabledMod(); + + /* //KIND OF BROKEN NOW AND ALSO PRETTY USELESS// + + var initSonglist = CoolUtil.coolTextFile(Paths.txt('freeplaySonglist')); + for (i in 0...initSonglist.length) + { + if(initSonglist[i] != null && initSonglist[i].length > 0) { + var songArray:Array = initSonglist[i].split(":"); + addSong(songArray[0], 0, songArray[1], Std.parseInt(songArray[2])); + } + }*/ + + #if PRELOAD_ALL + if (!curPlaying) Conductor.changeBPM(TitleState.titleJSON.bpm); + #end + + bg = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + bg.antialiasing = ClientPrefs.globalAntialiasing; + add(bg); + bg.screenCenter(); + + grpSongs = new FlxTypedGroup(); + add(grpSongs); + + for (i in 0...songs.length) + { + var songText:Alphabet = new Alphabet(90, 320, songs[i].songName, true); + songText.isMenuItem = true; + songText.targetY = i - curSelected; + grpSongs.add(songText); + + var maxWidth = 980; + if (songText.width > maxWidth) + { + songText.scaleX = maxWidth / songText.width; + } + songText.snapToPosition(); + + Paths.currentModDirectory = songs[i].folder; + var icon:HealthIcon = new HealthIcon(songs[i].songCharacter); + icon.sprTracker = songText; + + // using a FlxGroup is too much fuss! + iconArray.push(icon); + add(icon); + + // songText.x += 40; + // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! + // songText.screenCenter(X); + } + WeekData.setDirectoryFromWeek(); + + scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32); + scoreText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT); + + scoreBG = new FlxSprite(scoreText.x - 6, 0).makeGraphic(1, 66, 0xFF000000); + scoreBG.alpha = 0.6; + add(scoreBG); + + diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24); + diffText.font = scoreText.font; + add(diffText); + + add(scoreText); + + missingTextBG = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + missingTextBG.alpha = 0.6; + missingTextBG.visible = false; + add(missingTextBG); + + missingText = new FlxText(50, 0, FlxG.width - 100, '', 24); + missingText.setFormat(Paths.font("vcr.ttf"), 24, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + missingText.scrollFactor.set(); + missingText.visible = false; + add(missingText); + + if(curSelected >= songs.length) curSelected = 0; + bg.color = songs[curSelected].color; + intendedColor = bg.color; + + if(lastDifficultyName == '') + { + lastDifficultyName = CoolUtil.defaultDifficulty; + } + curDifficulty = Math.round(Math.max(0, CoolUtil.defaultDifficulties.indexOf(lastDifficultyName))); + + if(curPlaying) + { + iconArray[instPlaying].canBounce = true; + } + + changeSelection(); + changeDiff(); + + var swag:Alphabet = new Alphabet(1, 0, "swag"); + + // JUST DOIN THIS SHIT FOR TESTING!!! + /* + var md:String = Markdown.markdownToHtml(Assets.getText('CHANGELOG.md')); + + var texFel:TextField = new TextField(); + texFel.width = FlxG.width; + texFel.height = FlxG.height; + // texFel. + texFel.htmlText = md; + + FlxG.stage.addChild(texFel); + + // scoreText.textField.htmlText = md; + + trace(md); + */ + + var textBG:FlxSprite = new FlxSprite(0, FlxG.height - 26).makeGraphic(FlxG.width, 26, 0xFF000000); + textBG.alpha = 0.6; + add(textBG); + + #if PRELOAD_ALL + #if android + var leText:String = "Press X to listen to the Song / Press C to open the Gameplay Changers Menu / Press Y to Reset your Score and Accuracy."; + var size:Int = 16; + #else + var leText:String = "Press SPACE to listen to the Song / Press CTRL to open the Gameplay Changers Menu / Press RESET to Reset your Score and Accuracy."; + var size:Int = 16; + #end + #else + var leText:String = "Press C to open the Gameplay Changers Menu / Press Y to Reset your Score and Accuracy."; + var size:Int = 18; + #end + var text:FlxText = new FlxText(textBG.x, textBG.y + 4, FlxG.width, leText, size); + text.setFormat(Paths.font("vcr.ttf"), size, FlxColor.WHITE, RIGHT); + text.scrollFactor.set(); + add(text); + + #if android + addVirtualPad(LEFT_FULL, A_B_C_X_Y_Z); + #end + + super.create(); + } + + override function closeSubState() { + changeSelection(0, false); + persistentUpdate = true; + super.closeSubState(); + } + + public function addSong(songName:String, weekNum:Int, songCharacter:String, color:Int) + { + songs.push(new SongMetadata(songName, weekNum, songCharacter, color)); + } + + function weekIsLocked(name:String):Bool { + var leWeek:WeekData = WeekData.weeksLoaded.get(name); + return (!leWeek.startUnlocked && leWeek.weekBefore.length > 0 && (!StoryMenuState.weekCompleted.exists(leWeek.weekBefore) || !StoryMenuState.weekCompleted.get(leWeek.weekBefore))); + } + + /*public function addWeek(songs:Array, weekNum:Int, weekColor:Int, ?songCharacters:Array) + { + if (songCharacters == null) + songCharacters = ['bf']; + + var num:Int = 0; + for (song in songs) + { + addSong(song, weekNum, songCharacters[num]); + this.songs[this.songs.length-1].color = weekColor; + + if (songCharacters.length != 1) + num++; + } + }*/ + + public static var instPlaying:Int = -1; + public static var vocals:FlxSound = null; + var holdTime:Float = 0; + override function update(elapsed:Float) + { + if (FlxG.sound.music != null) + Conductor.songPosition = FlxG.sound.music.time; + + if (FlxG.sound.music.volume < 0.7) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + + for (i in 0...iconArray.length) + { + iconArray[i].scale.set(FlxMath.lerp(iconArray[i].scale.x, 1, elapsed * 9), + FlxMath.lerp(iconArray[i].scale.y, 1, elapsed * 9)); + } + + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, CoolUtil.boundTo(elapsed * 24, 0, 1))); + lerpRating = FlxMath.lerp(lerpRating, intendedRating, CoolUtil.boundTo(elapsed * 12, 0, 1)); + + if (Math.abs(lerpScore - intendedScore) <= 10) + lerpScore = intendedScore; + if (Math.abs(lerpRating - intendedRating) <= 0.01) + lerpRating = intendedRating; + + var ratingSplit:Array = Std.string(Highscore.floorDecimal(lerpRating * 100, 2)).split('.'); + if(ratingSplit.length < 2) { //No decimals, add an empty space + ratingSplit.push(''); + } + + while(ratingSplit[1].length < 2) { //Less than 2 decimals in it, add decimals then + ratingSplit[1] += '0'; + } + + scoreText.text = 'PERSONAL BEST: ' + lerpScore + ' (' + ratingSplit.join('.') + '%)'; + positionHighscore(); + + var upP = controls.UI_UP_P; + var downP = controls.UI_DOWN_P; + var accepted = controls.ACCEPT; + var space = FlxG.keys.justPressed.SPACE #if android || virtualPad.buttonX.justPressed #end; + var ctrl = FlxG.keys.justPressed.CONTROL #if android || virtualPad.buttonC.justPressed #end; + + var shiftMult:Int = 1; + if (FlxG.keys.pressed.SHIFT #if android || virtualPad.buttonZ.pressed #end) shiftMult = 3; + + if(songs.length > 1) + { + if (upP) + { + changeSelection(-shiftMult); + holdTime = 0; + } + if (downP) + { + changeSelection(shiftMult); + holdTime = 0; + } + + if(controls.UI_DOWN || controls.UI_UP) + { + var checkLastHold:Int = Math.floor((holdTime - 0.5) * 10); + holdTime += elapsed; + var checkNewHold:Int = Math.floor((holdTime - 0.5) * 10); + if(holdTime > 0.5 && checkNewHold - checkLastHold > 0) + { + changeSelection((checkNewHold - checkLastHold) * (controls.UI_UP ? -shiftMult : shiftMult)); + changeDiff(); + } + } + + if(FlxG.mouse.wheel != 0) + { + FlxG.sound.play(Paths.sound('scrollMenu'), 0.2); + changeSelection(-shiftMult * FlxG.mouse.wheel, false); + changeDiff(); + } + } + + if (controls.UI_LEFT_P) + changeDiff(-1); + else if (controls.UI_RIGHT_P) + changeDiff(1); + else if (upP || downP) changeDiff(); + + if (controls.BACK) + { + persistentUpdate = false; + if(colorTween != null) { + colorTween.cancel(); + } + FlxG.sound.play(Paths.sound('cancelMenu')); + MusicBeatState.switchState(new MainMenuState()); + } + + if(ctrl) + { + #if android + removeVirtualPad(); + #end + persistentUpdate = false; + openSubState(new GameplayChangersSubstate()); + } + else if(space) + { + requiredRamLoad = 0; + noteCount = 0; + function playSong() { + #if PRELOAD_ALL + destroyFreeplayVocals(); + FlxG.sound.music.volume = 0; + Paths.currentModDirectory = songs[curSelected].folder; + var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName.toLowerCase()); + if (PlayState.SONG.needsVoices) + vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song)); + else + vocals = new FlxSound(); + + FlxG.sound.list.add(vocals); + FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 0.7); + vocals.play(); + vocals.persist = true; + vocals.looped = true; + vocals.volume = 0.7; + instPlaying = curSelected; + Conductor.changeBPM(PlayState.SONG.bpm); + for (i in 0...iconArray.length) + iconArray[i].canBounce = false; + iconArray[instPlaying].canBounce = true; + curPlaying = true; + #end + + if (FlxG.keys.pressed.SHIFT #if android || virtualPad.buttonZ.pressed #end) { + for (section in PlayState.SONG.notes) { + noteCount += section.sectionNotes.length; + requiredRamLoad += 72872 * section.sectionNotes.length; + } + CoolUtil.coolError("There are " + FlxStringUtil.formatMoney(noteCount, false) + " notes in this chart!\nWith Show Notes turned on, you'd need " + formatCompactNumber(requiredRamLoad / 2) + " of ram to load this.", "JS Engine Chart Diagnosis"); + } + } + function songJsonPopup() { //you pressed space, but the song's ogg files don't exist + var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); + trace(poop + '\'s .ogg does not exist!'); + FlxG.sound.play(Paths.sound('invalidJSON')); + FlxG.camera.shake(0.05, 0.05); + var funnyText = new FlxText(12, FlxG.height - 24, 0, "Invalid Song!"); + funnyText.scrollFactor.set(); + funnyText.screenCenter(); + funnyText.x = 5; + funnyText.y = FlxG.height/2 - 64; + funnyText.setFormat("vcr.ttf", 64, FlxColor.RED, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + add(funnyText); + FlxTween.tween(funnyText, {alpha: 0}, 0.9, { + onComplete: _ -> { + remove(funnyText, true); + funnyText.destroy(); + } + }); + } + var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); + var songLowercase:String = Paths.formatToSongPath(songs[curSelected].songName); + #if desktop + if(instPlaying != curSelected) + { + if(sys.FileSystem.exists(Paths.inst(songLowercase + '/' + poop)) || sys.FileSystem.exists(Paths.json(songLowercase + '/' + poop)) || sys.FileSystem.exists(Paths.modsJson(songLowercase + '/' + poop))) + playSong(); + else + songJsonPopup(); + } + #else + if(instPlaying != curSelected) + { + if(OpenFlAssets.exists(Paths.inst(songLowercase + '/' + poop)) || OpenFlAssets.exists(Paths.json(songLowercase + '/' + poop))) + playSong(); + else + songJsonPopup(); + } + #end + } + + else if (accepted) + { + + persistentUpdate = false; + var songLowercase:String = Paths.formatToSongPath(songs[curSelected].songName); + var poop:String = Highscore.formatSong(songLowercase, curDifficulty); + /*#if MODS_ALLOWED + if(!sys.FileSystem.exists(Paths.modsJson(songLowercase + '/' + poop)) && !sys.FileSystem.exists(Paths.json(songLowercase + '/' + poop))) { + #else + if(!OpenFlAssets.exists(Paths.json(songLowercase + '/' + poop))) { + #end + poop = songLowercase; + curDifficulty = 1; + trace('Couldnt find file'); + }*/ + trace(poop); + + if(sys.FileSystem.exists(Paths.modsJson(songLowercase + '/' + poop)) || sys.FileSystem.exists(Paths.json(songLowercase + '/' + poop))) {//fix an issue where any song in the mods folder would return an error even if both the json and song files existed + PlayState.SONG = Song.loadFromJson(poop, songLowercase); + PlayState.isStoryMode = false; + PlayState.storyDifficulty = curDifficulty; + + trace('CURRENT WEEK: ' + WeekData.getWeekFileName()); + if(colorTween != null) { + colorTween.cancel(); + } + + curPlaying = false; + + if (FlxG.keys.pressed.SHIFT #if android || virtualPad.buttonZ.pressed #end) { + LoadingState.loadAndSwitchState(new ChartingState()); + }else{ + LoadingState.loadAndSwitchState(new PlayState()); + } + + FlxG.sound.music.volume = 0; + + destroyFreeplayVocals(); + + } else { + if(sys.FileSystem.exists(Paths.inst(poop + '/' + poop)) && !sys.FileSystem.exists(Paths.json(poop + '/' + poop))) { //the json doesn't exist, but the song files do, or you put a typo in the name + CoolUtil.coolError("The JSON's name does not match with " + poop + "!\nTry making them match.", "JS Engine Anti-Crash Tool"); + } else if(sys.FileSystem.exists(Paths.json(poop + '/' + poop)) && !sys.FileSystem.exists(Paths.inst(poop + '/' + poop))) {//the json exists, but the song files don't + CoolUtil.coolError("Your song seems to not have an Inst.ogg, check the folder name in 'songs'!", "JS Engine Anti-Crash Tool"); + } else if(!sys.FileSystem.exists(Paths.json(poop + '/' + poop)) && !sys.FileSystem.exists(Paths.inst(poop + '/' + poop))) { //neither the json nor the song files actually exist + CoolUtil.coolError("It appears that " + poop + " doesn't actually have a JSON, nor does it actually have voices/instrumental files!\nMaybe try fixing its name in weeks/" + WeekData.getWeekFileName() + "?", "JS Engine Anti-Crash Tool"); + } + } + } + else if (controls.RESET #if android || virtualPad.buttonY.justPressed #end) { + #if android + removeVirtualPad(); + #end + persistentUpdate = false; + openSubState(new ResetScoreSubState(songs[curSelected].songName, curDifficulty, songs[curSelected].songCharacter)); + FlxG.sound.play(Paths.sound('scrollMenu')); + } + super.update(elapsed); + } + + public static function destroyFreeplayVocals() { + if(vocals != null) { + vocals.stop(); + vocals.destroy(); + } + vocals = null; + } + + function changeDiff(change:Int = 0) + { + curDifficulty += change; + + if (curDifficulty < 0) + curDifficulty = CoolUtil.difficulties.length-1; + if (curDifficulty >= CoolUtil.difficulties.length) + curDifficulty = 0; + + lastDifficultyName = CoolUtil.difficulties[curDifficulty]; + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + intendedRating = Highscore.getRating(songs[curSelected].songName, curDifficulty); + #end + + PlayState.storyDifficulty = curDifficulty; + diffText.text = '< ' + CoolUtil.difficultyString() + ' >'; + positionHighscore(); + } + + public static function formatCompactNumber(number:Float):String //this entire function is ai generated LMAO + { + var suffixes:Array = [' bytes', ' KB', ' MB', ' GB', 'TB']; + var magnitude:Int = 0; + var num:Float = number; + + while (num >= 1000.0 && magnitude < suffixes.length - 1) + { + num /= 1000.0; + magnitude++; + } + + // Use the floor value for the compact representation + var compactValue:Float = Math.floor(num * 100) / 100; + if (compactValue <= 0.001) { + return "0"; //Return 0 if compactValue = null + } else { + return compactValue + (magnitude == 0 ? "" : "") + suffixes[magnitude]; + } + } + + function changeSelection(change:Int = 0, playSound:Bool = true) + { + if(playSound) FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + + curSelected += change; + + if (curSelected < 0) + curSelected = songs.length - 1; + if (curSelected >= songs.length) + curSelected = 0; + + var newColor:Int = songs[curSelected].color; + if(newColor != intendedColor) { + if(colorTween != null) { + colorTween.cancel(); + } + intendedColor = newColor; + colorTween = FlxTween.color(bg, 1, bg.color, intendedColor, { + onComplete: function(twn:FlxTween) { + colorTween = null; + } + }); + } + + // selector.y = (70 * curSelected) + 30; + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + intendedRating = Highscore.getRating(songs[curSelected].songName, curDifficulty); + #end + + var bullShit:Int = 0; + + for (i in 0...iconArray.length) + { + iconArray[i].alpha = 0.6; + } + + iconArray[curSelected].alpha = 1; + + for (item in grpSongs.members) + { + item.targetY = bullShit - curSelected; + bullShit++; + + item.alpha = 0.6; + // item.setGraphicSize(Std.int(item.width * 0.8)); + + if (item.targetY == 0) + { + item.alpha = 1; + // item.setGraphicSize(Std.int(item.width)); + } + } + + Paths.currentModDirectory = songs[curSelected].folder; + PlayState.storyWeek = songs[curSelected].week; + + CoolUtil.difficulties = CoolUtil.defaultDifficulties.copy(); + var diffStr:String = WeekData.getCurrentWeek().difficulties; + if(diffStr != null) diffStr = diffStr.trim(); //Fuck you HTML5 + + if(diffStr != null && diffStr.length > 0) + { + var diffs:Array = diffStr.split(','); + var i:Int = diffs.length - 1; + while (i > 0) + { + if(diffs[i] != null) + { + diffs[i] = diffs[i].trim(); + if(diffs[i].length < 1) diffs.remove(diffs[i]); + } + --i; + } + + if(diffs.length > 0 && diffs[0].length > 0) + { + CoolUtil.difficulties = diffs; + } + } + + if(CoolUtil.difficulties.contains(CoolUtil.defaultDifficulty)) + { + curDifficulty = Math.round(Math.max(0, CoolUtil.defaultDifficulties.indexOf(CoolUtil.defaultDifficulty))); + } + else + { + curDifficulty = 0; + } + + var newPos:Int = CoolUtil.difficulties.indexOf(lastDifficultyName); + //trace('Pos of ' + lastDifficultyName + ' is ' + newPos); + if(newPos > -1) + { + curDifficulty = newPos; + } + } + + private function positionHighscore() { + scoreText.x = FlxG.width - scoreText.width - 6; + + scoreBG.scale.x = FlxG.width - scoreText.x + 6; + scoreBG.x = FlxG.width - (scoreBG.scale.x / 2); + diffText.x = Std.int(scoreBG.x + (scoreBG.width / 2)); + diffText.x -= diffText.width / 2; + } + override function beatHit() { + super.beatHit(); + + if (curPlaying) + iconArray[instPlaying].bounce(); + } + var _drawDistance:Int = 4; + var _lastVisibles:Array = []; + public function updateTexts(elapsed:Float = 0.0) + { + lerpSelected = FlxMath.lerp(lerpSelected, curSelected, FlxMath.bound(elapsed * 9.6, 0, 1)); + for (i in _lastVisibles) + { + grpSongs.members[i].visible = grpSongs.members[i].active = false; + iconArray[i].visible = iconArray[i].active = false; + } + _lastVisibles = []; + + var min:Int = Math.round(Math.max(0, Math.min(songs.length, lerpSelected - _drawDistance))); + var max:Int = Math.round(Math.max(0, Math.min(songs.length, lerpSelected + _drawDistance))); + for (i in min...max) + { + var item:Alphabet = grpSongs.members[i]; + item.visible = item.active = true; + item.x = ((item.targetY - lerpSelected) * item.distancePerItem.x) + item.startPosition.x; + item.y = ((item.targetY - lerpSelected) * 1.3 * item.distancePerItem.y) + item.startPosition.y; + + var icon:HealthIcon = iconArray[i]; + icon.visible = icon.active = true; + _lastVisibles.push(i); + } + } +} + +class SongMetadata +{ + public var songName:String = ""; + public var week:Int = 0; + public var songCharacter:String = ""; + public var color:Int = -7179779; + public var folder:String = ""; + + public function new(song:String, week:Int, songCharacter:String, color:Int) + { + this.songName = song; + this.week = week; + this.songCharacter = songCharacter; + this.color = color; + this.folder = Paths.currentModDirectory; + if(this.folder == null) this.folder = ''; + } } \ No newline at end of file diff --git a/source/GameplayChangersSubstate.hx b/source/GameplayChangersSubstate.hx index 884eccd694c..74af8672752 100644 --- a/source/GameplayChangersSubstate.hx +++ b/source/GameplayChangersSubstate.hx @@ -1,649 +1,649 @@ -package; - -#if desktop -import Discord.DiscordClient; -#end -import flash.text.TextField; -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.addons.display.FlxGridOverlay; -#if android -import flixel.addons.transition.FlxTransitionableState; -#end -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.math.FlxMath; -import flixel.text.FlxText; -import flixel.util.FlxColor; -import lime.utils.Assets; -import flixel.FlxSubState; -import flash.text.TextField; -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.util.FlxSave; -import haxe.Json; -import flixel.tweens.FlxEase; -import flixel.tweens.FlxTween; -import flixel.util.FlxTimer; -import flixel.input.keyboard.FlxKey; -import flixel.graphics.FlxGraphic; -import Controls; - -using StringTools; - -class GameplayChangersSubstate extends MusicBeatSubstate -{ - private var curOption:GameplayOption = null; - private var curSelected:Int = 0; - private var optionsArray:Array = []; - - private var grpOptions:FlxTypedGroup; - private var checkboxGroup:FlxTypedGroup; - private var grpTexts:FlxTypedGroup; - public static var inThePauseMenu:Bool = false; - public var pauseState:PauseSubState; - - function getOptions() - { - var skip:Bool = inThePauseMenu; - - var goption:GameplayOption = new GameplayOption('Scroll Type', 'scrolltype', 'string', 'multiplicative', ["multiplicative", "constant"]); - optionsArray.push(goption); - - var option:GameplayOption = new GameplayOption('Scroll Speed', 'scrollspeed', 'float', 1); - option.scrollSpeed = 2.0; - option.minValue = 0.35; - option.changeValue = 0.05; - option.decimals = 2; - if (goption.getValue() != "constant") - { - option.displayFormat = '%vX'; - option.maxValue = 100; - } - else - { - option.displayFormat = "%v"; - option.maxValue = 200; - } - optionsArray.push(option); - - #if !html5 - var option:GameplayOption = new GameplayOption('Playback Rate', 'songspeed', 'float', 1); - option.scrollSpeed = 3; - option.minValue = 0.01; - option.maxValue = 30; - if (ClientPrefs.moreSpecificSpeed) - { - option.changeValue = 0.01; - } else - { - option.changeValue = 0.05; - } - option.displayFormat = '%vX'; - option.decimals = 2; - optionsArray.push(option); - #end - - var option:GameplayOption = new GameplayOption('Health Gain Multiplier', 'healthgain', 'float', 1); - option.scrollSpeed = 5; - option.minValue = -1; - option.maxValue = 50; - option.changeValue = 0.1; - option.displayFormat = '%vX'; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Health Loss Multiplier', 'healthloss', 'float', 1); - option.scrollSpeed = 2.5; - option.minValue = -1; - option.maxValue = 50; - option.changeValue = 0.1; - option.displayFormat = '%vX'; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Instakill on Miss', 'instakill', 'bool', false); - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Sicks Only', 'onlySicks', 'bool', false); - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Practice Mode', 'practice', 'bool', false); - optionsArray.push(option); - option.onChange = onChangePractice; //Changing onChange is only needed if you want to make a special interaction after it changes the value - - var option:GameplayOption = new GameplayOption('Botplay', 'botplay', 'bool', false); - optionsArray.push(option); - option.onChange = onChangeBotplay; //Changing onChange is only needed if you want to make a special interaction after it changes the value - - var option:GameplayOption = new GameplayOption('Play as Opponent', 'opponentplay', 'bool', false); - option.onChange = onChangeChartOption; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Opponent Health Drain', 'opponentdrain', 'bool', false); - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Health Drain Level: ', 'drainlevel', 'float', 1); - option.scrollSpeed = 2; - option.minValue = -1; - option.maxValue = 10; - option.changeValue = 0.1; - option.displayFormat = '%vX'; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Random Mode', 'randommode', 'bool', false); - option.onChange = onChangeChartOption; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Stair Mode', 'stairmode', 'bool', false); - option.onChange = onChangeChartOption; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Wave Mode', 'wavemode', 'bool', false); - option.onChange = onChangeChartOption; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Flip Mode', 'flip', 'bool', false); - option.onChange = onChangeChartOption; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('One Key', 'onekey', 'bool', false); - option.onChange = onChangeChartOption; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Jack Amount: ', 'jacks', 'float', 0); - option.onChange = onChangeChartOption; - option.scrollSpeed = 6; - option.minValue = 0; - option.maxValue = 100; - option.changeValue = 1; - option.displayFormat = '%v'; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Random Playback Rate', 'randomspeed', 'bool', false); - option.onChange = onChangeChartOption; - optionsArray.push(option); - - var option:GameplayOption = new GameplayOption('Troll Mode', 'thetrollingever', 'bool', false); - option.onChange = onChangeChartOption; - optionsArray.push(option); - } - - public function getOptionByName(name:String) - { - for(i in optionsArray) - { - var opt:GameplayOption = i; - if (opt.name == name) - return opt; - } - return null; - } - - public function new(?pause:MusicBeatSubstate = null) - { - super(); - - var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - bg.alpha = 0.6; - add(bg); - - // avoids lagspikes while scrolling through menus! - grpOptions = new FlxTypedGroup(); - add(grpOptions); - - grpTexts = new FlxTypedGroup(); - add(grpTexts); - - checkboxGroup = new FlxTypedGroup(); - add(checkboxGroup); - - getOptions(); - - for (i in 0...optionsArray.length) - { - var optionText:Alphabet = new Alphabet(200, 360, optionsArray[i].name, true); - optionText.isMenuItem = true; - optionText.scaleX = 0.8; - optionText.scaleY = 0.8; - optionText.targetY = i; - grpOptions.add(optionText); - - if(optionsArray[i].type == 'bool') { - optionText.x += 110; - optionText.startPosition.x += 110; - optionText.snapToPosition(); - var checkbox:CheckboxThingie = new CheckboxThingie(optionText.x - 105, optionText.y, optionsArray[i].getValue() == true); - checkbox.sprTracker = optionText; - checkbox.offsetX -= 32; - checkbox.offsetY = -120; - checkbox.ID = i; - checkboxGroup.add(checkbox); - } else { - optionText.snapToPosition(); - var valueText:AttachedText = new AttachedText(Std.string(optionsArray[i].getValue()), optionText.width, -72, true, 0.8); - valueText.sprTracker = optionText; - valueText.copyAlpha = true; - valueText.ID = i; - grpTexts.add(valueText); - optionsArray[i].setChild(valueText); - } - updateTextFrom(optionsArray[i]); - } - - changeSelection(); - reloadCheckboxes(); - - #if android - addVirtualPad(LEFT_FULL, A_B_C); - addPadCamera(); - #end - - cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; - } - - override function destroy() { - if (inThePauseMenu) { - PlayState.instance.changeTheSettingsBitch(); - inThePauseMenu = false; - } - super.destroy(); - } - - var nextAccept:Int = 5; - var holdTime:Float = 0; - var holdValue:Float = 0; - override function update(elapsed:Float) - { - if (controls.UI_UP_P) - { - changeSelection(-1); - } - if (controls.UI_DOWN_P) - { - changeSelection(1); - } - - if (controls.BACK) { - #if android - FlxTransitionableState.skipNextTransOut = true; - FlxG.resetState(); - #else - close(); - #end - ClientPrefs.saveSettings(); - FlxG.sound.play(Paths.sound('cancelMenu')); - } - - if(nextAccept <= 0) - { - var usesCheckbox = true; - if(curOption.type != 'bool') - { - usesCheckbox = false; - } - - if(usesCheckbox) - { - if(controls.ACCEPT) - { - FlxG.sound.play(Paths.sound('scrollMenu')); - curOption.setValue((curOption.getValue() == true) ? false : true); - curOption.change(); - reloadCheckboxes(); - } - } else { - if(controls.UI_LEFT || controls.UI_RIGHT) { - var pressed = (controls.UI_LEFT_P || controls.UI_RIGHT_P); - if(holdTime > 0.5 || pressed) { - if(pressed) { - var add:Dynamic = null; - if(curOption.type != 'string') { - add = controls.UI_LEFT ? -curOption.changeValue : curOption.changeValue; - } - - switch(curOption.type) - { - case 'int' | 'float' | 'percent': - holdValue = curOption.getValue() + add; - if(holdValue < curOption.minValue) holdValue = curOption.minValue; - else if (holdValue > curOption.maxValue) holdValue = curOption.maxValue; - - switch(curOption.type) - { - case 'int': - holdValue = Math.round(holdValue); - curOption.setValue(holdValue); - - case 'float' | 'percent': - holdValue = FlxMath.roundDecimal(holdValue, curOption.decimals); - curOption.setValue(holdValue); - } - - case 'string': - var num:Int = curOption.curOption; //lol - if(controls.UI_LEFT_P) --num; - else num++; - - if(num < 0) { - num = curOption.options.length - 1; - } else if(num >= curOption.options.length) { - num = 0; - } - - curOption.curOption = num; - curOption.setValue(curOption.options[num]); //lol - - if (curOption.name == "Scroll Type") - { - var oOption:GameplayOption = getOptionByName("Scroll Speed"); - if (oOption != null) - { - if (curOption.getValue() == "constant") - { - oOption.displayFormat = "%v"; - oOption.maxValue = 60; - } - else - { - oOption.displayFormat = "%vX"; - oOption.maxValue = 30; - if(oOption.getValue() > 30) oOption.setValue(30); - } - updateTextFrom(oOption); - } - } - //trace(curOption.options[num]); - } - updateTextFrom(curOption); - curOption.change(); - FlxG.sound.play(Paths.sound('scrollMenu')); - } else if(curOption.type != 'string') { - holdValue = Math.max(curOption.minValue, Math.min(curOption.maxValue, holdValue + curOption.scrollSpeed * elapsed * (controls.UI_LEFT ? -1 : 1))); - - switch(curOption.type) - { - case 'int': - curOption.setValue(Math.round(holdValue)); - - case 'float' | 'percent': - var blah:Float = Math.max(curOption.minValue, Math.min(curOption.maxValue, holdValue + curOption.changeValue - (holdValue % curOption.changeValue))); - curOption.setValue(FlxMath.roundDecimal(blah, curOption.decimals)); - } - updateTextFrom(curOption); - curOption.change(); - } - } - - if(curOption.type != 'string') { - holdTime += elapsed; - } - } else if(controls.UI_LEFT_R || controls.UI_RIGHT_R) { - clearHold(); - } - } - if(controls.RESET && FlxG.keys.pressed.SHIFT #if android || virtualPad.buttonC.justPressed #end) - { - for (i in 0...optionsArray.length) - { - var leOption:GameplayOption = optionsArray[i]; - leOption.setValue(leOption.defaultValue); - if(leOption.type != 'bool') - { - if(leOption.type == 'string') - { - leOption.curOption = leOption.options.indexOf(leOption.getValue()); - } - updateTextFrom(leOption); - } - - if(leOption.name == 'Scroll Speed') - { - leOption.displayFormat = "%vX"; - leOption.maxValue = 60; - if(leOption.getValue() > 60) - { - leOption.setValue(60); - } - updateTextFrom(leOption); - } - leOption.change(); - } - FlxG.sound.play(Paths.sound('cancelMenu')); - reloadCheckboxes(); - } - - if(controls.RESET && !FlxG.keys.pressed.SHIFT) - { - var leOption:GameplayOption = optionsArray[curSelected]; - leOption.setValue(leOption.defaultValue); - if(leOption.type != 'bool') - { - if(leOption.type == 'string') - { - leOption.curOption = leOption.options.indexOf(leOption.getValue()); - } - updateTextFrom(leOption); - } - - if(leOption.name == 'Scroll Speed') - { - leOption.displayFormat = "%vX"; - leOption.maxValue = 60; - if(leOption.getValue() > 60) - { - leOption.setValue(60); - } - updateTextFrom(leOption); - } - leOption.change(); - FlxG.sound.play(Paths.sound('cancelMenu')); - reloadCheckboxes(); - } - } - - if(nextAccept > 0) { - nextAccept -= 1; - } - super.update(elapsed); - } - - function updateTextFrom(option:GameplayOption) { - var text:String = option.displayFormat; - var val:Dynamic = option.getValue(); - if(option.type == 'percent') val *= 100; - var def:Dynamic = option.defaultValue; - option.text = text.replace('%v', val).replace('%d', def); - } - - function clearHold() - { - if(holdTime > 0.5) { - FlxG.sound.play(Paths.sound('scrollMenu')); - } - holdTime = 0; - } - - function onChangePractice() - { - if(inThePauseMenu) - { - trace ("you really thought you would get away with it, invalidated your score"); - PlayState.playerIsCheating = true; - } - } - function onChangeChartOption() - { - if(inThePauseMenu) - { - trace ("HEY! You changed an option that requires a chart restart!"); - PauseSubState.requireRestart = true; - } - } - function onChangeBotplay() - { - if(inThePauseMenu) - { - trace ("you really thought you would get away with it, invalidated your score"); - PlayState.playerIsCheating = true; - } - } - - function changeSelection(change:Int = 0) - { - curSelected += change; - if (curSelected < 0) - curSelected = optionsArray.length - 1; - if (curSelected >= optionsArray.length) - curSelected = 0; - - var bullShit:Int = 0; - - for (item in grpOptions.members) { - item.targetY = bullShit - curSelected; - bullShit++; - - item.alpha = 0.6; - if (item.targetY == 0) { - item.alpha = 1; - } - } - for (text in grpTexts) { - text.alpha = 0.6; - if(text.ID == curSelected) { - text.alpha = 1; - } - } - curOption = optionsArray[curSelected]; //shorter lol - FlxG.sound.play(Paths.sound('scrollMenu')); - } - - function reloadCheckboxes() { - for (checkbox in checkboxGroup) { - checkbox.daValue = (optionsArray[checkbox.ID].getValue() == true); - } - } -} - -class GameplayOption -{ - private var child:Alphabet; - public var text(get, set):String; - public var onChange:Void->Void = null; //Pressed enter (on Bool type options) or pressed/held left/right (on other types) - - public var type(get, default):String = 'bool'; //bool, int (or integer), float (or fl), percent, string (or str) - // Bool will use checkboxes - // Everything else will use a text - - public var showBoyfriend:Bool = false; - public var scrollSpeed:Float = 50; //Only works on int/float, defines how fast it scrolls per second while holding left/right - - private var variable:String = null; //Variable from ClientPrefs.hx's gameplaySettings - public var defaultValue:Dynamic = null; - - public var curOption:Int = 0; //Don't change this - public var options:Array = null; //Only used in string type - public var changeValue:Dynamic = 1; //Only used in int/float/percent type, how much is changed when you PRESS - public var minValue:Dynamic = null; //Only used in int/float/percent type - public var maxValue:Dynamic = null; //Only used in int/float/percent type - public var decimals:Int = 1; //Only used in float/percent type - - public var displayFormat:String = '%v'; //How String/Float/Percent/Int values are shown, %v = Current value, %d = Default value - public var name:String = 'Unknown'; - - public function new(name:String, variable:String, type:String = 'bool', defaultValue:Dynamic = 'null variable value', ?options:Array = null) - { - this.name = name; - this.variable = variable; - this.type = type; - this.defaultValue = defaultValue; - this.options = options; - - if(defaultValue == 'null variable value') - { - switch(type) - { - case 'bool': - defaultValue = false; - case 'int' | 'float': - defaultValue = 0; - case 'percent': - defaultValue = 1; - case 'string': - defaultValue = ''; - if(options.length > 0) { - defaultValue = options[0]; - } - } - } - - if(getValue() == null) { - setValue(defaultValue); - } - - switch(type) - { - case 'string': - var num:Int = options.indexOf(getValue()); - if(num > -1) { - curOption = num; - } - - case 'percent': - displayFormat = '%v%'; - changeValue = 0.01; - minValue = 0; - maxValue = 1; - scrollSpeed = 0.5; - decimals = 2; - } - } - - public function change() - { - //nothing lol - if(onChange != null) { - onChange(); - } - } - - public function getValue():Dynamic - { - return ClientPrefs.gameplaySettings.get(variable); - } - public function setValue(value:Dynamic) - { - ClientPrefs.gameplaySettings.set(variable, value); - } - - public function setChild(child:Alphabet) - { - this.child = child; - } - - private function get_text() - { - if(child != null) { - return child.text; - } - return null; - } - private function set_text(newValue:String = '') - { - if(child != null) { - child.text = newValue; - } - return null; - } - - private function get_type() - { - var newValue:String = 'bool'; - switch(type.toLowerCase().trim()) - { - case 'int' | 'float' | 'percent' | 'string': newValue = type; - case 'integer': newValue = 'int'; - case 'str': newValue = 'string'; - case 'fl': newValue = 'float'; - } - type = newValue; - return type; - } +package; + +#if desktop +import Discord.DiscordClient; +#end +import flash.text.TextField; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +#if android +import flixel.addons.transition.FlxTransitionableState; +#end +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import lime.utils.Assets; +import flixel.FlxSubState; +import flash.text.TextField; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.util.FlxSave; +import haxe.Json; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxTimer; +import flixel.input.keyboard.FlxKey; +import flixel.graphics.FlxGraphic; +import Controls; + +using StringTools; + +class GameplayChangersSubstate extends MusicBeatSubstate +{ + private var curOption:GameplayOption = null; + private var curSelected:Int = 0; + private var optionsArray:Array = []; + + private var grpOptions:FlxTypedGroup; + private var checkboxGroup:FlxTypedGroup; + private var grpTexts:FlxTypedGroup; + public static var inThePauseMenu:Bool = false; + public var pauseState:PauseSubState; + + function getOptions() + { + var skip:Bool = inThePauseMenu; + + var goption:GameplayOption = new GameplayOption('Scroll Type', 'scrolltype', 'string', 'multiplicative', ["multiplicative", "constant"]); + optionsArray.push(goption); + + var option:GameplayOption = new GameplayOption('Scroll Speed', 'scrollspeed', 'float', 1); + option.scrollSpeed = 2.0; + option.minValue = 0.35; + option.changeValue = 0.05; + option.decimals = 2; + if (goption.getValue() != "constant") + { + option.displayFormat = '%vX'; + option.maxValue = 100; + } + else + { + option.displayFormat = "%v"; + option.maxValue = 200; + } + optionsArray.push(option); + + #if !html5 + var option:GameplayOption = new GameplayOption('Playback Rate', 'songspeed', 'float', 1); + option.scrollSpeed = 3; + option.minValue = 0.01; + option.maxValue = 30; + if (ClientPrefs.moreSpecificSpeed) + { + option.changeValue = 0.01; + } else + { + option.changeValue = 0.05; + } + option.displayFormat = '%vX'; + option.decimals = 2; + optionsArray.push(option); + #end + + var option:GameplayOption = new GameplayOption('Health Gain Multiplier', 'healthgain', 'float', 1); + option.scrollSpeed = 5; + option.minValue = -1; + option.maxValue = 50; + option.changeValue = 0.1; + option.displayFormat = '%vX'; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Health Loss Multiplier', 'healthloss', 'float', 1); + option.scrollSpeed = 2.5; + option.minValue = -1; + option.maxValue = 50; + option.changeValue = 0.1; + option.displayFormat = '%vX'; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Instakill on Miss', 'instakill', 'bool', false); + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Sicks Only', 'onlySicks', 'bool', false); + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Practice Mode', 'practice', 'bool', false); + optionsArray.push(option); + option.onChange = onChangePractice; //Changing onChange is only needed if you want to make a special interaction after it changes the value + + var option:GameplayOption = new GameplayOption('Botplay', 'botplay', 'bool', false); + optionsArray.push(option); + option.onChange = onChangeBotplay; //Changing onChange is only needed if you want to make a special interaction after it changes the value + + var option:GameplayOption = new GameplayOption('Play as Opponent', 'opponentplay', 'bool', false); + option.onChange = onChangeChartOption; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Opponent Health Drain', 'opponentdrain', 'bool', false); + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Health Drain Level: ', 'drainlevel', 'float', 1); + option.scrollSpeed = 2; + option.minValue = -1; + option.maxValue = 10; + option.changeValue = 0.1; + option.displayFormat = '%vX'; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Random Mode', 'randommode', 'bool', false); + option.onChange = onChangeChartOption; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Stair Mode', 'stairmode', 'bool', false); + option.onChange = onChangeChartOption; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Wave Mode', 'wavemode', 'bool', false); + option.onChange = onChangeChartOption; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Flip Mode', 'flip', 'bool', false); + option.onChange = onChangeChartOption; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('One Key', 'onekey', 'bool', false); + option.onChange = onChangeChartOption; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Jack Amount: ', 'jacks', 'float', 0); + option.onChange = onChangeChartOption; + option.scrollSpeed = 6; + option.minValue = 0; + option.maxValue = 100; + option.changeValue = 1; + option.displayFormat = '%v'; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Random Playback Rate', 'randomspeed', 'bool', false); + option.onChange = onChangeChartOption; + optionsArray.push(option); + + var option:GameplayOption = new GameplayOption('Troll Mode', 'thetrollingever', 'bool', false); + option.onChange = onChangeChartOption; + optionsArray.push(option); + } + + public function getOptionByName(name:String) + { + for(i in optionsArray) + { + var opt:GameplayOption = i; + if (opt.name == name) + return opt; + } + return null; + } + + public function new(?pause:MusicBeatSubstate = null) + { + super(); + + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + bg.alpha = 0.6; + add(bg); + + // avoids lagspikes while scrolling through menus! + grpOptions = new FlxTypedGroup(); + add(grpOptions); + + grpTexts = new FlxTypedGroup(); + add(grpTexts); + + checkboxGroup = new FlxTypedGroup(); + add(checkboxGroup); + + getOptions(); + + for (i in 0...optionsArray.length) + { + var optionText:Alphabet = new Alphabet(200, 360, optionsArray[i].name, true); + optionText.isMenuItem = true; + optionText.scaleX = 0.8; + optionText.scaleY = 0.8; + optionText.targetY = i; + grpOptions.add(optionText); + + if(optionsArray[i].type == 'bool') { + optionText.x += 110; + optionText.startPosition.x += 110; + optionText.snapToPosition(); + var checkbox:CheckboxThingie = new CheckboxThingie(optionText.x - 105, optionText.y, optionsArray[i].getValue() == true); + checkbox.sprTracker = optionText; + checkbox.offsetX -= 32; + checkbox.offsetY = -120; + checkbox.ID = i; + checkboxGroup.add(checkbox); + } else { + optionText.snapToPosition(); + var valueText:AttachedText = new AttachedText(Std.string(optionsArray[i].getValue()), optionText.width, -72, true, 0.8); + valueText.sprTracker = optionText; + valueText.copyAlpha = true; + valueText.ID = i; + grpTexts.add(valueText); + optionsArray[i].setChild(valueText); + } + updateTextFrom(optionsArray[i]); + } + + changeSelection(); + reloadCheckboxes(); + + #if android + addVirtualPad(LEFT_FULL, A_B_C); + addPadCamera(); + #end + + cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; + } + + override function destroy() { + if (inThePauseMenu) { + PlayState.instance.changeTheSettingsBitch(); + inThePauseMenu = false; + } + super.destroy(); + } + + var nextAccept:Int = 5; + var holdTime:Float = 0; + var holdValue:Float = 0; + override function update(elapsed:Float) + { + if (controls.UI_UP_P) + { + changeSelection(-1); + } + if (controls.UI_DOWN_P) + { + changeSelection(1); + } + + if (controls.BACK) { + #if android + FlxTransitionableState.skipNextTransOut = true; + FlxG.resetState(); + #else + close(); + #end + ClientPrefs.saveSettings(); + FlxG.sound.play(Paths.sound('cancelMenu')); + } + + if(nextAccept <= 0) + { + var usesCheckbox = true; + if(curOption.type != 'bool') + { + usesCheckbox = false; + } + + if(usesCheckbox) + { + if(controls.ACCEPT) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + curOption.setValue((curOption.getValue() == true) ? false : true); + curOption.change(); + reloadCheckboxes(); + } + } else { + if(controls.UI_LEFT || controls.UI_RIGHT) { + var pressed = (controls.UI_LEFT_P || controls.UI_RIGHT_P); + if(holdTime > 0.5 || pressed) { + if(pressed) { + var add:Dynamic = null; + if(curOption.type != 'string') { + add = controls.UI_LEFT ? -curOption.changeValue : curOption.changeValue; + } + + switch(curOption.type) + { + case 'int' | 'float' | 'percent': + holdValue = curOption.getValue() + add; + if(holdValue < curOption.minValue) holdValue = curOption.minValue; + else if (holdValue > curOption.maxValue) holdValue = curOption.maxValue; + + switch(curOption.type) + { + case 'int': + holdValue = Math.round(holdValue); + curOption.setValue(holdValue); + + case 'float' | 'percent': + holdValue = FlxMath.roundDecimal(holdValue, curOption.decimals); + curOption.setValue(holdValue); + } + + case 'string': + var num:Int = curOption.curOption; //lol + if(controls.UI_LEFT_P) --num; + else num++; + + if(num < 0) { + num = curOption.options.length - 1; + } else if(num >= curOption.options.length) { + num = 0; + } + + curOption.curOption = num; + curOption.setValue(curOption.options[num]); //lol + + if (curOption.name == "Scroll Type") + { + var oOption:GameplayOption = getOptionByName("Scroll Speed"); + if (oOption != null) + { + if (curOption.getValue() == "constant") + { + oOption.displayFormat = "%v"; + oOption.maxValue = 60; + } + else + { + oOption.displayFormat = "%vX"; + oOption.maxValue = 30; + if(oOption.getValue() > 30) oOption.setValue(30); + } + updateTextFrom(oOption); + } + } + //trace(curOption.options[num]); + } + updateTextFrom(curOption); + curOption.change(); + FlxG.sound.play(Paths.sound('scrollMenu')); + } else if(curOption.type != 'string') { + holdValue = Math.max(curOption.minValue, Math.min(curOption.maxValue, holdValue + curOption.scrollSpeed * elapsed * (controls.UI_LEFT ? -1 : 1))); + + switch(curOption.type) + { + case 'int': + curOption.setValue(Math.round(holdValue)); + + case 'float' | 'percent': + var blah:Float = Math.max(curOption.minValue, Math.min(curOption.maxValue, holdValue + curOption.changeValue - (holdValue % curOption.changeValue))); + curOption.setValue(FlxMath.roundDecimal(blah, curOption.decimals)); + } + updateTextFrom(curOption); + curOption.change(); + } + } + + if(curOption.type != 'string') { + holdTime += elapsed; + } + } else if(controls.UI_LEFT_R || controls.UI_RIGHT_R) { + clearHold(); + } + } + if(controls.RESET && FlxG.keys.pressed.SHIFT #if android || virtualPad.buttonC.justPressed #end) + { + for (i in 0...optionsArray.length) + { + var leOption:GameplayOption = optionsArray[i]; + leOption.setValue(leOption.defaultValue); + if(leOption.type != 'bool') + { + if(leOption.type == 'string') + { + leOption.curOption = leOption.options.indexOf(leOption.getValue()); + } + updateTextFrom(leOption); + } + + if(leOption.name == 'Scroll Speed') + { + leOption.displayFormat = "%vX"; + leOption.maxValue = 60; + if(leOption.getValue() > 60) + { + leOption.setValue(60); + } + updateTextFrom(leOption); + } + leOption.change(); + } + FlxG.sound.play(Paths.sound('cancelMenu')); + reloadCheckboxes(); + } + + if(controls.RESET && !FlxG.keys.pressed.SHIFT) + { + var leOption:GameplayOption = optionsArray[curSelected]; + leOption.setValue(leOption.defaultValue); + if(leOption.type != 'bool') + { + if(leOption.type == 'string') + { + leOption.curOption = leOption.options.indexOf(leOption.getValue()); + } + updateTextFrom(leOption); + } + + if(leOption.name == 'Scroll Speed') + { + leOption.displayFormat = "%vX"; + leOption.maxValue = 60; + if(leOption.getValue() > 60) + { + leOption.setValue(60); + } + updateTextFrom(leOption); + } + leOption.change(); + FlxG.sound.play(Paths.sound('cancelMenu')); + reloadCheckboxes(); + } + } + + if(nextAccept > 0) { + nextAccept -= 1; + } + super.update(elapsed); + } + + function updateTextFrom(option:GameplayOption) { + var text:String = option.displayFormat; + var val:Dynamic = option.getValue(); + if(option.type == 'percent') val *= 100; + var def:Dynamic = option.defaultValue; + option.text = text.replace('%v', val).replace('%d', def); + } + + function clearHold() + { + if(holdTime > 0.5) { + FlxG.sound.play(Paths.sound('scrollMenu')); + } + holdTime = 0; + } + + function onChangePractice() + { + if(inThePauseMenu) + { + trace ("you really thought you would get away with it, invalidated your score"); + PlayState.playerIsCheating = true; + } + } + function onChangeChartOption() + { + if(inThePauseMenu) + { + trace ("HEY! You changed an option that requires a chart restart!"); + PauseSubState.requireRestart = true; + } + } + function onChangeBotplay() + { + if(inThePauseMenu) + { + trace ("you really thought you would get away with it, invalidated your score"); + PlayState.playerIsCheating = true; + } + } + + function changeSelection(change:Int = 0) + { + curSelected += change; + if (curSelected < 0) + curSelected = optionsArray.length - 1; + if (curSelected >= optionsArray.length) + curSelected = 0; + + var bullShit:Int = 0; + + for (item in grpOptions.members) { + item.targetY = bullShit - curSelected; + bullShit++; + + item.alpha = 0.6; + if (item.targetY == 0) { + item.alpha = 1; + } + } + for (text in grpTexts) { + text.alpha = 0.6; + if(text.ID == curSelected) { + text.alpha = 1; + } + } + curOption = optionsArray[curSelected]; //shorter lol + FlxG.sound.play(Paths.sound('scrollMenu')); + } + + function reloadCheckboxes() { + for (checkbox in checkboxGroup) { + checkbox.daValue = (optionsArray[checkbox.ID].getValue() == true); + } + } +} + +class GameplayOption +{ + private var child:Alphabet; + public var text(get, set):String; + public var onChange:Void->Void = null; //Pressed enter (on Bool type options) or pressed/held left/right (on other types) + + public var type(get, default):String = 'bool'; //bool, int (or integer), float (or fl), percent, string (or str) + // Bool will use checkboxes + // Everything else will use a text + + public var showBoyfriend:Bool = false; + public var scrollSpeed:Float = 50; //Only works on int/float, defines how fast it scrolls per second while holding left/right + + private var variable:String = null; //Variable from ClientPrefs.hx's gameplaySettings + public var defaultValue:Dynamic = null; + + public var curOption:Int = 0; //Don't change this + public var options:Array = null; //Only used in string type + public var changeValue:Dynamic = 1; //Only used in int/float/percent type, how much is changed when you PRESS + public var minValue:Dynamic = null; //Only used in int/float/percent type + public var maxValue:Dynamic = null; //Only used in int/float/percent type + public var decimals:Int = 1; //Only used in float/percent type + + public var displayFormat:String = '%v'; //How String/Float/Percent/Int values are shown, %v = Current value, %d = Default value + public var name:String = 'Unknown'; + + public function new(name:String, variable:String, type:String = 'bool', defaultValue:Dynamic = 'null variable value', ?options:Array = null) + { + this.name = name; + this.variable = variable; + this.type = type; + this.defaultValue = defaultValue; + this.options = options; + + if(defaultValue == 'null variable value') + { + switch(type) + { + case 'bool': + defaultValue = false; + case 'int' | 'float': + defaultValue = 0; + case 'percent': + defaultValue = 1; + case 'string': + defaultValue = ''; + if(options.length > 0) { + defaultValue = options[0]; + } + } + } + + if(getValue() == null) { + setValue(defaultValue); + } + + switch(type) + { + case 'string': + var num:Int = options.indexOf(getValue()); + if(num > -1) { + curOption = num; + } + + case 'percent': + displayFormat = '%v%'; + changeValue = 0.01; + minValue = 0; + maxValue = 1; + scrollSpeed = 0.5; + decimals = 2; + } + } + + public function change() + { + //nothing lol + if(onChange != null) { + onChange(); + } + } + + public function getValue():Dynamic + { + return ClientPrefs.gameplaySettings.get(variable); + } + public function setValue(value:Dynamic) + { + ClientPrefs.gameplaySettings.set(variable, value); + } + + public function setChild(child:Alphabet) + { + this.child = child; + } + + private function get_text() + { + if(child != null) { + return child.text; + } + return null; + } + private function set_text(newValue:String = '') + { + if(child != null) { + child.text = newValue; + } + return null; + } + + private function get_type() + { + var newValue:String = 'bool'; + switch(type.toLowerCase().trim()) + { + case 'int' | 'float' | 'percent' | 'string': newValue = type; + case 'integer': newValue = 'int'; + case 'str': newValue = 'string'; + case 'fl': newValue = 'float'; + } + type = newValue; + return type; + } } \ No newline at end of file diff --git a/source/Main.hx b/source/Main.hx index 90d1118d004..a53282e7ccb 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -1,230 +1,230 @@ -package; - -import flixel.graphics.FlxGraphic; -import flixel.FlxG; -import flixel.FlxGame; -import flixel.FlxState; -import openfl.Assets; -import openfl.Lib; -import flixel.util.FlxColor; -import openfl.display.FPS; -import openfl.display.Sprite; -import openfl.events.Event; -import openfl.display.StageScaleMode; -import lime.app.Application; -#if desktop -import Discord.DiscordClient; -import cpp.vm.Gc; -#end -// crash handler stuff -#if CRASH_HANDLER -import openfl.events.UncaughtErrorEvent; -import haxe.CallStack; -import haxe.io.Path; -import sys.FileSystem; -import sys.io.File; -import sys.io.Process; -#end -#if (target.threaded && sys && desktop) -import sys.thread.ElasticThreadPool; -#end - -using StringTools; - -class Main extends Sprite { - var game = { - width: 1280, - height: 720, - initialState: TitleState, - zoom: -1.0, - framerate: 60, - skipSplash: false, - startFullscreen: false - }; - - public static var fpsVar:FPS; - public static var changeID:Int = 0; - - public static var textGenerations:Int = 0; - - public static var __superCoolErrorMessagesArray:Array = [ - "A fatal error has occ- wait what?", - "missigno.", - "oopsie daisies!! you did a fucky wucky!!", - "i think you fogot a semicolon", - "null balls reference", - "get friday night funkd'", - "engine skipped a heartbeat", - "Impossible...", - "Patience is key for success... Don't give up.", - "It's no longer in its early stages... is it?", - "It took me half a day to code that in", - "You should make an issue... NOW!!", - "> Crash Handler written by: yoshicrafter29", - "broken ch-... wait what are we talking about", - "could not access variable you.dad", - "What have you done...", - "THERE ARENT COUGARS IN SCRIPTING!!! I HEARD IT!!", - "no, thats not from system.windows.forms", - "you better link a screenshot if you make an issue, or at least the crash.txt", - "stack trace more like dunno i dont have any jokes", - "oh the misery. everybody wants to be my enemy", - "have you heard of soulles dx", - "i thought it was invincible", - "did you deleted coconut.png", - "have you heard of missing json's cousin null function reference", - "sad that linux users wont see this banger of a crash handler", - "woopsie", - "oopsie", - "woops", - "silly me", - "my bad", - "first time, huh?", - "did somebody say yoga", - "we forget a thousand things everyday... make sure this is one of them.", - "SAY GOODBYE TO YOUR KNEECAPS, CHUCKLEHEAD", - "motherfucking ordinal 344 (TaskDialog) forcing me to create a even fancier window", - "Died due to missing a sawblade. (Press Space to dodge!)", - "yes rico, kaboom.", - "hey, while in freeplay, press shift while pressing space", - "goofy ahh engine", - "pssst, try typing debug7 in the options menu", - "this crash handler is sponsored by rai-", - "", - "did you know a jiffy is an actual measurement of time", - "how many hurt notes did you put", - "FPS: 0", - "\r\ni am a secret message", - "this is garnet", - "Error: Sorry i already have a girlfriend", - "did you know theres a total of 51 silly messages", - "whoopsies looks like i forgot to fix this", - "Game used Crash. It's super effective!" - ]; - - // You can pretty much ignore everything from here on - your code should go in your states. - - public static function main():Void { - Lib.current.addChild(new Main()); - } - - public function new() { - super(); - - SUtil.gameCrashCheck(); - if (stage != null) { - init(); - } else { - addEventListener(Event.ADDED_TO_STAGE, init); - } - } - - private function init(?E:Event):Void { - if (hasEventListener(Event.ADDED_TO_STAGE)) { - removeEventListener(Event.ADDED_TO_STAGE, init); - } - - setupGame(); - } - - #if (target.threaded && sys && desktop) - public static var threadPool:ElasticThreadPool; - #end - - private function setupGame():Void { - var stageWidth:Int = Lib.current.stage.stageWidth; - var stageHeight:Int = Lib.current.stage.stageHeight; - - if (game.zoom == -1.0) { - var ratioX:Float = stageWidth / game.width; - var ratioY:Float = stageHeight / game.height; - game.zoom = Math.min(ratioX, ratioY); - game.width = Math.ceil(stageWidth / game.zoom); - game.height = Math.ceil(stageHeight / game.zoom); - game.skipSplash = true; // if the default flixel splash screen should be skipped - } - - SUtil.doTheCheck(); - - ClientPrefs.loadDefaultKeys(); - addChild(new FlxGame(game.width, game.height, game.initialState, game.framerate, game.framerate, game.skipSplash, game.startFullscreen)); - - fpsVar = new FPS(10, 3, 0xFFFFFF); - addChild(fpsVar); - Lib.current.stage.align = "tl"; - Lib.current.stage.scaleMode = StageScaleMode.NO_SCALE; - if (fpsVar != null) { - fpsVar.visible = ClientPrefs.showFPS; - } - - #if (target.threaded && sys && desktop) - threadPool = new ElasticThreadPool(12, 30); - #end - - FlxG.autoPause = false; - - #if html5 - FlxG.mouse.visible = false; - #end - - #if CRASH_HANDLER - Lib.current.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onCrash); - #end - - #if desktop - if (!DiscordClient.isInitialized) { - DiscordClient.initialize(); - Application.current.window.onClose.add(function() { - DiscordClient.shutdown(); - }); - } - #end - } - - public function changeFPSColor(color:FlxColor) { - fpsVar.textColor = color; - } - - // Code was entirely made by sqirra-rng for their fnf engine named "Izzy Engine", big props to them!!! - // very cool person for real they don't get enough credit for their work - #if (CRASH_HANDLER) - function onCrash(e:UncaughtErrorEvent):Void { - var errorMessage:String = ""; - var path:String; - var callStack:Array = CallStack.exceptionStack(true); - var dateNow:String = Date.now().toString(); - - dateNow = dateNow.replace(" ", "_"); - dateNow = dateNow.replace(":", "'"); - - path = SUtil.getPath() + "crash/" + "JSEngine_" + dateNow + ".log"; - - for (stackItem in callStack) { - switch (stackItem) { - case FilePos(s, file, line, column): - errorMessage += file + " (Line " + line + ")\n"; - default: - Sys.println(stackItem); - } - } - - errorMessage += "\nUncaught Error: " - + e.error - + "\nPlease don't report this error to the GitHub page\n\n> Crash Handler written by: sqirra-rng"; - - if (!FileSystem.exists(SUtil.getPath() + "crash/")) - FileSystem.createDirectory(SUtil.getPath() + "crash/"); - - File.saveContent(path, errorMessage + "\n"); - - Sys.println(errorMessage); - Sys.println("Crash dump saved in " + Path.normalize(path)); - - Application.current.window.alert("Error! JS Engine v" + MainMenuState.psychEngineJSVersion, errorMessage); - #if desktop - DiscordClient.shutdown(); - #end - Sys.exit(1); - } - #end +package; + +import flixel.graphics.FlxGraphic; +import flixel.FlxG; +import flixel.FlxGame; +import flixel.FlxState; +import openfl.Assets; +import openfl.Lib; +import flixel.util.FlxColor; +import openfl.display.FPS; +import openfl.display.Sprite; +import openfl.events.Event; +import openfl.display.StageScaleMode; +import lime.app.Application; +#if desktop +import Discord.DiscordClient; +import cpp.vm.Gc; +#end +// crash handler stuff +#if CRASH_HANDLER +import openfl.events.UncaughtErrorEvent; +import haxe.CallStack; +import haxe.io.Path; +import sys.FileSystem; +import sys.io.File; +import sys.io.Process; +#end +#if (target.threaded && sys && desktop) +import sys.thread.ElasticThreadPool; +#end + +using StringTools; + +class Main extends Sprite { + var game = { + width: 1280, + height: 720, + initialState: TitleState, + zoom: -1.0, + framerate: 60, + skipSplash: false, + startFullscreen: false + }; + + public static var fpsVar:FPS; + public static var changeID:Int = 0; + + public static var textGenerations:Int = 0; + + public static var __superCoolErrorMessagesArray:Array = [ + "A fatal error has occ- wait what?", + "missigno.", + "oopsie daisies!! you did a fucky wucky!!", + "i think you fogot a semicolon", + "null balls reference", + "get friday night funkd'", + "engine skipped a heartbeat", + "Impossible...", + "Patience is key for success... Don't give up.", + "It's no longer in its early stages... is it?", + "It took me half a day to code that in", + "You should make an issue... NOW!!", + "> Crash Handler written by: yoshicrafter29", + "broken ch-... wait what are we talking about", + "could not access variable you.dad", + "What have you done...", + "THERE ARENT COUGARS IN SCRIPTING!!! I HEARD IT!!", + "no, thats not from system.windows.forms", + "you better link a screenshot if you make an issue, or at least the crash.txt", + "stack trace more like dunno i dont have any jokes", + "oh the misery. everybody wants to be my enemy", + "have you heard of soulles dx", + "i thought it was invincible", + "did you deleted coconut.png", + "have you heard of missing json's cousin null function reference", + "sad that linux users wont see this banger of a crash handler", + "woopsie", + "oopsie", + "woops", + "silly me", + "my bad", + "first time, huh?", + "did somebody say yoga", + "we forget a thousand things everyday... make sure this is one of them.", + "SAY GOODBYE TO YOUR KNEECAPS, CHUCKLEHEAD", + "motherfucking ordinal 344 (TaskDialog) forcing me to create a even fancier window", + "Died due to missing a sawblade. (Press Space to dodge!)", + "yes rico, kaboom.", + "hey, while in freeplay, press shift while pressing space", + "goofy ahh engine", + "pssst, try typing debug7 in the options menu", + "this crash handler is sponsored by rai-", + "", + "did you know a jiffy is an actual measurement of time", + "how many hurt notes did you put", + "FPS: 0", + "\r\ni am a secret message", + "this is garnet", + "Error: Sorry i already have a girlfriend", + "did you know theres a total of 51 silly messages", + "whoopsies looks like i forgot to fix this", + "Game used Crash. It's super effective!" + ]; + + // You can pretty much ignore everything from here on - your code should go in your states. + + public static function main():Void { + Lib.current.addChild(new Main()); + } + + public function new() { + super(); + + SUtil.gameCrashCheck(); + if (stage != null) { + init(); + } else { + addEventListener(Event.ADDED_TO_STAGE, init); + } + } + + private function init(?E:Event):Void { + if (hasEventListener(Event.ADDED_TO_STAGE)) { + removeEventListener(Event.ADDED_TO_STAGE, init); + } + + setupGame(); + } + + #if (target.threaded && sys && desktop) + public static var threadPool:ElasticThreadPool; + #end + + private function setupGame():Void { + var stageWidth:Int = Lib.current.stage.stageWidth; + var stageHeight:Int = Lib.current.stage.stageHeight; + + if (game.zoom == -1.0) { + var ratioX:Float = stageWidth / game.width; + var ratioY:Float = stageHeight / game.height; + game.zoom = Math.min(ratioX, ratioY); + game.width = Math.ceil(stageWidth / game.zoom); + game.height = Math.ceil(stageHeight / game.zoom); + game.skipSplash = true; // if the default flixel splash screen should be skipped + } + + SUtil.doTheCheck(); + + ClientPrefs.loadDefaultKeys(); + addChild(new FlxGame(game.width, game.height, game.initialState, game.framerate, game.framerate, game.skipSplash, game.startFullscreen)); + + fpsVar = new FPS(10, 3, 0xFFFFFF); + addChild(fpsVar); + Lib.current.stage.align = "tl"; + Lib.current.stage.scaleMode = StageScaleMode.NO_SCALE; + if (fpsVar != null) { + fpsVar.visible = ClientPrefs.showFPS; + } + + #if (target.threaded && sys && desktop) + threadPool = new ElasticThreadPool(12, 30); + #end + + FlxG.autoPause = false; + + #if html5 + FlxG.mouse.visible = false; + #end + + #if CRASH_HANDLER + Lib.current.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onCrash); + #end + + #if desktop + if (!DiscordClient.isInitialized) { + DiscordClient.initialize(); + Application.current.window.onClose.add(function() { + DiscordClient.shutdown(); + }); + } + #end + } + + public function changeFPSColor(color:FlxColor) { + fpsVar.textColor = color; + } + + // Code was entirely made by sqirra-rng for their fnf engine named "Izzy Engine", big props to them!!! + // very cool person for real they don't get enough credit for their work + #if (CRASH_HANDLER) + function onCrash(e:UncaughtErrorEvent):Void { + var errorMessage:String = ""; + var path:String; + var callStack:Array = CallStack.exceptionStack(true); + var dateNow:String = Date.now().toString(); + + dateNow = dateNow.replace(" ", "_"); + dateNow = dateNow.replace(":", "'"); + + path = SUtil.getPath() + "crash/" + "JSEngine_" + dateNow + ".log"; + + for (stackItem in callStack) { + switch (stackItem) { + case FilePos(s, file, line, column): + errorMessage += file + " (Line " + line + ")\n"; + default: + Sys.println(stackItem); + } + } + + errorMessage += "\nUncaught Error: " + + e.error + + "\nPlease don't report this error to the GitHub page\n\n> Crash Handler written by: sqirra-rng"; + + if (!FileSystem.exists(SUtil.getPath() + "crash/")) + FileSystem.createDirectory(SUtil.getPath() + "crash/"); + + File.saveContent(path, errorMessage + "\n"); + + Sys.println(errorMessage); + Sys.println("Crash dump saved in " + Path.normalize(path)); + + Application.current.window.alert("Error! JS Engine v" + MainMenuState.psychEngineJSVersion, errorMessage); + #if desktop + DiscordClient.shutdown(); + #end + Sys.exit(1); + } + #end } \ No newline at end of file diff --git a/source/Paths.hx b/source/Paths.hx index 8faa7ac02e4..52a57e67892 100644 --- a/source/Paths.hx +++ b/source/Paths.hx @@ -1,660 +1,660 @@ -package; - -import animateatlas.AtlasFrameMaker; - -import flixel.graphics.frames.FlxFrame.FlxFrameAngle; -import flixel.graphics.frames.FlxAtlasFrames; -import flixel.graphics.FlxGraphic; -import flixel.math.FlxPoint; -import flixel.math.FlxRect; -import flixel.FlxG; -import openfl.display.BitmapData; -import openfl.display3D.textures.RectangleTexture; -import openfl.utils.AssetType; -import openfl.utils.Assets as OpenFlAssets; -import openfl.system.System; -import openfl.geom.Rectangle; - -import lime.utils.Assets; -import flash.media.Sound; - -#if sys -import sys.io.File; -import sys.FileSystem; -#end -import flixel.graphics.FlxGraphic; -import openfl.display.BitmapData; -import haxe.Json; - -import openfl.display3D.textures.RectangleTexture; -import lime.media.vorbis.VorbisFile; -import lime.media.AudioBuffer; - -import flash.media.Sound; - -using StringTools; - -class Paths -{ - inline public static var SOUND_EXT = #if web "mp3" #else "ogg" #end; - inline public static var VIDEO_EXT = "mp4"; - - #if MODS_ALLOWED - public static var ignoreModFolders:Array = [ - 'characters', - 'custom_events', - 'custom_notetypes', - 'data', - 'songs', - 'music', - 'sounds', - 'shaders', - 'videos', - 'images', - 'stages', - 'weeks', - 'fonts', - 'scripts', - 'achievements' - ]; - #end - - public static function excludeAsset(key:String) { - if (!dumpExclusions.contains(key)) - dumpExclusions.push(key); - } - - public static var dumpExclusions:Array = - [ - SUtil.getPath() + 'assets/music/freakyMenu.$SOUND_EXT', - SUtil.getPath() + 'assets/shared/music/breakfast.$SOUND_EXT', - SUtil.getPath() + 'assets/shared/music/tea-time.$SOUND_EXT', - ]; - /// haya I love you for the base cache dump I took to the max - public static function clearUnusedMemory() { - // clear non local assets in the tracked assets list - for (key in currentTrackedAssets.keys()) { - // if it is not currently contained within the used local assets - if (!localTrackedAssets.contains(key) && !dumpExclusions.contains(key)) { - var obj = currentTrackedAssets.get(key); - @:privateAccess - if (obj != null) { - // remove the key from all cache maps - FlxG.bitmap._cache.remove(key); - openfl.Assets.cache.removeBitmapData(key); - currentTrackedAssets.remove(key); - // and get rid of the object - obj.persist = false; // make sure the garbage collector actually clears it up - obj.destroyOnNoUse = true; - obj.destroy(); - } - } - } - // run the garbage collector for good measure lmfao - #if sys - openfl.system.System.gc(); - #elseif cpp - cpp.vm.Gc.run(); - #end - } - // define the locally tracked assets - public static var localTrackedAssets:Array = []; - public static function clearStoredMemory(?cleanUnused:Bool = false) { - // clear anything not in the tracked assets list - @:privateAccess - for (key in FlxG.bitmap._cache.keys()) - { - var obj = FlxG.bitmap._cache.get(key); - if (obj != null && !currentTrackedAssets.exists(key)) { - openfl.Assets.cache.removeBitmapData(key); - FlxG.bitmap._cache.remove(key); - obj.destroy(); - } - } - // clear all sounds that are cached - for (key in currentTrackedSounds.keys()) { - if (!localTrackedAssets.contains(key) - && !dumpExclusions.contains(key) && key != null) { - //trace('test: ' + dumpExclusions, key); - Assets.cache.clear(key); - currentTrackedSounds.remove(key); - } - } - // flags everything to be cleared out next unused memory clear - localTrackedAssets = []; - #if !html5 openfl.Assets.cache.clear("songs"); #end - } - - static public var currentModDirectory:String = ''; - static public var currentLevel:String; - static public function setCurrentLevel(name:String) - { - currentLevel = name.toLowerCase(); - } - - public static function getPath(file:String, type:AssetType, ?library:Null = null) - { - if (library != null) - return getLibraryPath(file, library); - - if (currentLevel != null) - { - var levelPath:String = ''; - if(currentLevel != 'shared') { - levelPath = getLibraryPathForce(file, currentLevel); - if (OpenFlAssets.exists(levelPath, type)) - return levelPath; - } - - levelPath = getLibraryPathForce(file, "shared"); - if (OpenFlAssets.exists(levelPath, type)) - return levelPath; - } - - return getPreloadPath(file); - } - - static public function getLibraryPath(file:String, library = "preload") - { - return if (library == "preload" || library == "default") getPreloadPath(file); else getLibraryPathForce(file, library); - } - - inline static function getLibraryPathForce(file:String, library:String) - { - var returnPath = '$library:assets/$library/$file'; - return returnPath; - } - - inline public static function getPreloadPath(file:String = '') - { - return 'assets/$file'; - } - - inline static public function file(file:String, type:AssetType = TEXT, ?library:String) - { - return getPath(file, type, library); - } - - inline static public function txt(key:String, ?library:String) - { - return getPath('data/$key.txt', TEXT, library); - } - - inline static public function xml(key:String, ?library:String) - { - return getPath('data/$key.xml', TEXT, library); - } - - inline static public function json(key:String, ?library:String) - { - return getPath('data/' + key + '.json', TEXT, library); - } - - inline static public function shaderFragment(key:String, ?library:String) - { - return getPath('shaders/$key.frag', TEXT, library); - } - inline static public function shaderVertex(key:String, ?library:String) - { - return getPath('shaders/$key.vert', TEXT, library); - } - inline static public function lua(key:String, ?library:String) - { - return getPath('$key.lua', TEXT, library); - } - //Video loading (part of it) - static public function video(key:String) - { - #if MODS_ALLOWED - var file:String = modsVideo(key); - if(FileSystem.exists(file)) { - return file; - } - #end - return SUtil.getPath() + 'assets/videos/$key.$VIDEO_EXT'; - } - //Sound loading. - static public function sound(key:String, ?library:String):Sound - { - var sound:Sound = returnSound('sounds', key, library); - return sound; - } - //Random sound loading. - inline static public function soundRandom(key:String, min:Int, max:Int, ?library:String) - { - return sound(key + FlxG.random.int(min, max), library); - } - //Music loading. Loads anything in assets/data/music, OR mods/data/music (if mods are allowed) - inline static public function music(key:String, ?library:String):Sound - { - var file:Sound = returnSound('music', key, library); - return file; - } - //Loads the Voices. Crucial for generateSong - inline static public function voices(song:String):Any - { - #if html5 - return 'songs:assets/songs/${formatToSongPath(song)}/Voices.$SOUND_EXT'; - #else - var songKey:String = '${formatToSongPath(song)}/Voices'; - var voices = returnSound('songs', songKey); - if (!ClientPrefs.progAudioLoad) voices = returnSoundFull('songs', songKey); - return voices; - #end - } - //Loads the instrumental. Crucial for generateSong - inline static public function inst(song:String):Any - { - #if html5 - return 'songs:assets/songs/${formatToSongPath(song)}/Inst.$SOUND_EXT'; - #else - var songKey:String = '${formatToSongPath(song)}/Inst'; - var inst = returnSound('songs', songKey); - if (!ClientPrefs.progAudioLoad) inst = returnSoundFull('songs', songKey); - return inst; - #end - } - -//Difficulty-specific Inst and Voices loading. Doesn't work so i've scrapped it for now but this was taken directly from Leather Engine - /* - static public function voices(song:String, ?difficulty:String) - { - if(difficulty != null) - { - if(Assets.exists('songs:assets/songs/${song.toLowerCase()}/Voices-$difficulty.$SOUND_EXT')) - { - return 'songs:assets/songs/${song.toLowerCase()}/Voices-$difficulty.$SOUND_EXT'; - } - } - - return 'songs:assets/songs/${song.toLowerCase()}/Voices.$SOUND_EXT'; - } - - static public function inst(song:String, ?difficulty:String) - { - if(difficulty != null) - { - if(Assets.exists('songs:assets/songs/${song.toLowerCase()}/Inst-$difficulty.$SOUND_EXT')) - { - return 'songs:assets/songs/${song.toLowerCase()}/Inst-$difficulty.$SOUND_EXT'; - } - } - - return 'songs:assets/songs/${song.toLowerCase()}/Inst.$SOUND_EXT'; - } - */ - //Loads images. - public static var currentTrackedAssets:Map = []; - static public function image(key:String, ?library:String = null, ?allowGPU:Bool = true):FlxGraphic - { - if (ClientPrefs.cacheOnGPU) { - var bitmap:BitmapData = null; - var file:String = null; - - #if MODS_ALLOWED - file = modsImages(key); - if (currentTrackedAssets.exists(file)) - { - localTrackedAssets.push(file); - return currentTrackedAssets.get(file); - } - else if (FileSystem.exists(file)) - bitmap = BitmapData.fromFile(file); - else - #end - { - file = getPath('images/$key.png', IMAGE, library); - if (currentTrackedAssets.exists(file)) - { - localTrackedAssets.push(file); - return currentTrackedAssets.get(file); - } - else if (OpenFlAssets.exists(file, IMAGE)) - bitmap = OpenFlAssets.getBitmapData(file); - } - - if (bitmap != null) - { - localTrackedAssets.push(file); - if (allowGPU && ClientPrefs.cacheOnGPU) - { - var texture:RectangleTexture = FlxG.stage.context3D.createRectangleTexture(bitmap.width, bitmap.height, BGRA, true); - texture.uploadFromBitmapData(bitmap); - bitmap.image.data = null; - bitmap.dispose(); - bitmap.disposeImage(); - bitmap = BitmapData.fromTexture(texture); - } - var newGraphic:FlxGraphic = FlxGraphic.fromBitmapData(bitmap, false, file); - newGraphic.persist = true; - newGraphic.destroyOnNoUse = false; - currentTrackedAssets.set(file, newGraphic); - return newGraphic; - } - - trace('oh no its returning null NOOOO ($file)'); - return null; - } else { - #if MODS_ALLOWED - var modKey:String = modsImages(key); - if(FileSystem.exists(modKey)) { - if(!currentTrackedAssets.exists(modKey)) { - var newBitmap:BitmapData = BitmapData.fromFile(modKey); - var newGraphic:FlxGraphic = FlxGraphic.fromBitmapData(newBitmap, false, modKey); - newGraphic.persist = true; - currentTrackedAssets.set(modKey, newGraphic); - } - localTrackedAssets.push(modKey); - return currentTrackedAssets.get(modKey); - } - #end - - var path = getPath('images/$key.png', IMAGE, library); - //trace(path); - if (OpenFlAssets.exists(path, IMAGE)) { - if(!currentTrackedAssets.exists(path)) { - var newGraphic:FlxGraphic = FlxG.bitmap.add(path, false, path); - newGraphic.persist = true; - currentTrackedAssets.set(path, newGraphic); - } - localTrackedAssets.push(path); - return currentTrackedAssets.get(path); - } - trace('oh no its returning null NOOOO (' + modKey + ')'); - return null; - } - } - - static public function getTextFromFile(key:String, ?ignoreMods:Bool = false):String - { - #if sys - #if MODS_ALLOWED - if (!ignoreMods && FileSystem.exists(modFolders(key))) - return File.getContent(modFolders(key)); - #end - - if (FileSystem.exists(SUtil.getPath() + getPreloadPath(key))) - return File.getContent(SUtil.getPath() + getPreloadPath(key)); - - if (currentLevel != null) - { - var levelPath:String = ''; - if(currentLevel != 'shared') { - levelPath = SUtil.getPath() + getLibraryPathForce(key, currentLevel); - if (FileSystem.exists(levelPath)) - return File.getContent(levelPath); - } - - levelPath = SUtil.getPath() + getLibraryPathForce(key, 'shared'); - if (FileSystem.exists(levelPath)) - return File.getContent(levelPath); - } - #end - return Assets.getText(getPath(key, TEXT)); - } - - inline static public function font(key:String) - { - #if MODS_ALLOWED - var file:String = modsFont(key); - if(FileSystem.exists(file)) { - return file; - } - #end - return SUtil.getPath() + 'assets/fonts/$key'; - } - - public static function fileExists(key:String, type:AssetType, ?ignoreMods:Bool = false, ?library:String) - { - #if MODS_ALLOWED - if(FileSystem.exists(mods(currentModDirectory + '/' + key)) || FileSystem.exists(mods(key))) { - return true; - } - #end - - if(OpenFlAssets.exists(getPath(key, type))) { - return true; - } - return false; - } - - inline static public function getSparrowAtlas(key:String, ?library:String):FlxAtlasFrames - { - #if MODS_ALLOWED - var imageLoaded:FlxGraphic = image(key); - var xmlExists:Bool = false; - if(FileSystem.exists(modsXml(key))) { - xmlExists = true; - } - - return FlxAtlasFrames.fromSparrow((imageLoaded != null ? imageLoaded : image(key, library)), (xmlExists ? File.getContent(modsXml(key)) : file('images/$key.xml', library))); - #else - return FlxAtlasFrames.fromSparrow(image(key, library), file('images/$key.xml', library)); - #end - } - - - inline static public function getPackerAtlas(key:String, ?library:String) - { - #if MODS_ALLOWED - var imageLoaded:FlxGraphic = image(key); - var txtExists:Bool = false; - if(FileSystem.exists(modsTxt(key))) { - txtExists = true; - } - - return FlxAtlasFrames.fromSpriteSheetPacker((imageLoaded != null ? imageLoaded : image(key, library)), (txtExists ? File.getContent(modsTxt(key)) : file('images/$key.txt', library))); - #else - return FlxAtlasFrames.fromSpriteSheetPacker(image(key, library), file('images/$key.txt', library)); - #end - } - - inline static public function formatToSongPath(path:String) { - var invalidChars = ~/[~&\\;:<>#]/; - var hideChars = ~/[.,'"%?!]/; - - var path = invalidChars.split(path.replace(' ', '-')).join("-"); - return hideChars.split(path).join("").toLowerCase(); - } - // completely rewritten asset loading? fuck! - public static var currentTrackedSounds:Map = []; - //Returns sounds which is useful for all the sfx - public static function returnSound(path:String, key:String, ?library:String, stream:Bool = false) { - var sound:Sound = null; - var file:String = null; - - #if MODS_ALLOWED - file = modsSounds(path, key); - if (currentTrackedSounds.exists(file)) { - localTrackedAssets.push(file); - return currentTrackedSounds.get(file); - } else if (FileSystem.exists(file)) { - #if lime_vorbis - if (stream) - sound = Sound.fromAudioBuffer(AudioBuffer.fromVorbisFile(VorbisFile.fromFile(file))); - else - #end - sound = Sound.fromFile(file); - } - else - #end - { - // I hate this so god damn much - var gottenPath:String = getPath('$path/$key.$SOUND_EXT', SOUND, library); - file = gottenPath.substring(gottenPath.indexOf(':') + 1, gottenPath.length); - if (path == 'songs') - gottenPath = 'songs:' + gottenPath; - if (currentTrackedSounds.exists(file)) - { - localTrackedAssets.push(file); - return currentTrackedSounds.get(file); - } - else if (OpenFlAssets.exists(gottenPath, SOUND)) - { - #if lime_vorbis - if (stream) - sound = OpenFlAssets.getMusic(gottenPath); - else - #end - sound = OpenFlAssets.getSound(gottenPath); - } - } - - if (sound != null) - { - localTrackedAssets.push(file); - currentTrackedSounds.set(file, sound); - return sound; - } - - trace('oh no its returning null NOOOO ($file)'); - return null; - } - //Ditto, but returns the full sound instead - public static function returnSoundFull(path:String, key:String, ?library:String) { - #if MODS_ALLOWED - var file:String = modsSounds(path, key); - if(FileSystem.exists(file)) { - if(!currentTrackedSounds.exists(file)) { - currentTrackedSounds.set(file, Sound.fromFile(file)); - } - localTrackedAssets.push(key); - return currentTrackedSounds.get(file); - } - #end - // I hate this so god damn much - var gottenPath:String = getPath('$path/$key.$SOUND_EXT', SOUND, library); - gottenPath = gottenPath.substring(gottenPath.indexOf(':') + 1, gottenPath.length); - // trace(gottenPath); - if(!currentTrackedSounds.exists(gottenPath)) - #if MODS_ALLOWED - currentTrackedSounds.set(gottenPath, Sound.fromFile('./' + gottenPath)); - #else - { - var folder:String = ''; - if(path == 'songs') folder = 'songs:'; - - currentTrackedSounds.set(gottenPath, OpenFlAssets.getSound(folder + getPath('$path/$key.$SOUND_EXT', SOUND, library))); - } - #end - localTrackedAssets.push(gottenPath); - return currentTrackedSounds.get(gottenPath); - } - - #if MODS_ALLOWED - //Loads mods. - inline static public function mods(key:String = '') { - return SUtil.getPath() + 'mods/' + key; - } - //Loads fonts in mods/fonts. - inline static public function modsFont(key:String) { - return modFolders('fonts/' + key); - } - //Loads jsons in mods/data. - inline static public function modsJson(key:String) { - return modFolders('data/' + key + '.json'); - } - //Loads videos in mods/videos. - inline static public function modsVideo(key:String) { - return modFolders('videos/' + key + '.' + VIDEO_EXT); - } - //Loads sounds in mods/sounds. - inline static public function modsSounds(path:String, key:String) { - return modFolders(path + '/' + key + '.' + SOUND_EXT); - } - //Loads images in mods/images. - inline static public function modsImages(key:String) { - return modFolders('images/' + key + '.png'); - } - //Loads xml files in mods/images. - inline static public function modsXml(key:String) { - return modFolders('images/' + key + '.xml'); - } - //Loads txt files in mods/images. - inline static public function modsTxt(key:String) { - return modFolders('images/' + key + '.txt'); - } - - /* Goes unused for now - - inline static public function modsShaderFragment(key:String, ?library:String) - { - return modFolders('shaders/'+key+'.frag'); - } - inline static public function modsShaderVertex(key:String, ?library:String) - { - return modFolders('shaders/'+key+'.vert'); - } - inline static public function modsAchievements(key:String) { - return modFolders('achievements/' + key + '.json'); - }*/ - - static public function modFolders(key:String) { - if(currentModDirectory != null && currentModDirectory.length > 0) { - var fileToCheck:String = mods(currentModDirectory + '/' + key); - if(FileSystem.exists(fileToCheck)) { - return fileToCheck; - } - } - - for(mod in getGlobalMods()){ - var fileToCheck:String = mods(mod + '/' + key); - if(FileSystem.exists(fileToCheck)) - return fileToCheck; - - } - return SUtil.getPath() + 'mods/' + key; - } - - public static var globalMods:Array = []; - - static public function getGlobalMods() - return globalMods; - - static public function pushGlobalMods() // prob a better way to do this but idc - { - globalMods = []; - var path:String = SUtil.getPath() + 'modsList.txt'; - if(FileSystem.exists(path)) - { - var list:Array = CoolUtil.coolTextFile(path); - for (i in list) - { - var dat = i.split("|"); - if (dat[1] == "1") - { - var folder = dat[0]; - var path = Paths.mods(folder + '/pack.json'); - if(FileSystem.exists(path)) { - try{ - var rawJson:String = File.getContent(path); - if(rawJson != null && rawJson.length > 0) { - var stuff:Dynamic = Json.parse(rawJson); - var global:Bool = Reflect.getProperty(stuff, "runsGlobally"); - if(global)globalMods.push(dat[0]); - } - } catch(e:Dynamic){ - trace(e); - } - } - } - } - } - return globalMods; - } - - static public function getModDirectories():Array { - var list:Array = []; - var modsFolder:String = mods(); - if(FileSystem.exists(modsFolder)) { - for (folder in FileSystem.readDirectory(modsFolder)) { - var path = haxe.io.Path.join([modsFolder, folder]); - if (sys.FileSystem.isDirectory(path) && !ignoreModFolders.contains(folder) && !list.contains(folder)) { - list.push(folder); - } - } - } - return list; - } - #end -} +package; + +import animateatlas.AtlasFrameMaker; + +import flixel.graphics.frames.FlxFrame.FlxFrameAngle; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.graphics.FlxGraphic; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.FlxG; +import openfl.display.BitmapData; +import openfl.display3D.textures.RectangleTexture; +import openfl.utils.AssetType; +import openfl.utils.Assets as OpenFlAssets; +import openfl.system.System; +import openfl.geom.Rectangle; + +import lime.utils.Assets; +import flash.media.Sound; + +#if sys +import sys.io.File; +import sys.FileSystem; +#end +import flixel.graphics.FlxGraphic; +import openfl.display.BitmapData; +import haxe.Json; + +import openfl.display3D.textures.RectangleTexture; +import lime.media.vorbis.VorbisFile; +import lime.media.AudioBuffer; + +import flash.media.Sound; + +using StringTools; + +class Paths +{ + inline public static var SOUND_EXT = #if web "mp3" #else "ogg" #end; + inline public static var VIDEO_EXT = "mp4"; + + #if MODS_ALLOWED + public static var ignoreModFolders:Array = [ + 'characters', + 'custom_events', + 'custom_notetypes', + 'data', + 'songs', + 'music', + 'sounds', + 'shaders', + 'videos', + 'images', + 'stages', + 'weeks', + 'fonts', + 'scripts', + 'achievements' + ]; + #end + + public static function excludeAsset(key:String) { + if (!dumpExclusions.contains(key)) + dumpExclusions.push(key); + } + + public static var dumpExclusions:Array = + [ + SUtil.getPath() + 'assets/music/freakyMenu.$SOUND_EXT', + SUtil.getPath() + 'assets/shared/music/breakfast.$SOUND_EXT', + SUtil.getPath() + 'assets/shared/music/tea-time.$SOUND_EXT', + ]; + /// haya I love you for the base cache dump I took to the max + public static function clearUnusedMemory() { + // clear non local assets in the tracked assets list + for (key in currentTrackedAssets.keys()) { + // if it is not currently contained within the used local assets + if (!localTrackedAssets.contains(key) && !dumpExclusions.contains(key)) { + var obj = currentTrackedAssets.get(key); + @:privateAccess + if (obj != null) { + // remove the key from all cache maps + FlxG.bitmap._cache.remove(key); + openfl.Assets.cache.removeBitmapData(key); + currentTrackedAssets.remove(key); + // and get rid of the object + obj.persist = false; // make sure the garbage collector actually clears it up + obj.destroyOnNoUse = true; + obj.destroy(); + } + } + } + // run the garbage collector for good measure lmfao + #if sys + openfl.system.System.gc(); + #elseif cpp + cpp.vm.Gc.run(); + #end + } + // define the locally tracked assets + public static var localTrackedAssets:Array = []; + public static function clearStoredMemory(?cleanUnused:Bool = false) { + // clear anything not in the tracked assets list + @:privateAccess + for (key in FlxG.bitmap._cache.keys()) + { + var obj = FlxG.bitmap._cache.get(key); + if (obj != null && !currentTrackedAssets.exists(key)) { + openfl.Assets.cache.removeBitmapData(key); + FlxG.bitmap._cache.remove(key); + obj.destroy(); + } + } + // clear all sounds that are cached + for (key in currentTrackedSounds.keys()) { + if (!localTrackedAssets.contains(key) + && !dumpExclusions.contains(key) && key != null) { + //trace('test: ' + dumpExclusions, key); + Assets.cache.clear(key); + currentTrackedSounds.remove(key); + } + } + // flags everything to be cleared out next unused memory clear + localTrackedAssets = []; + #if !html5 openfl.Assets.cache.clear("songs"); #end + } + + static public var currentModDirectory:String = ''; + static public var currentLevel:String; + static public function setCurrentLevel(name:String) + { + currentLevel = name.toLowerCase(); + } + + public static function getPath(file:String, type:AssetType, ?library:Null = null) + { + if (library != null) + return getLibraryPath(file, library); + + if (currentLevel != null) + { + var levelPath:String = ''; + if(currentLevel != 'shared') { + levelPath = getLibraryPathForce(file, currentLevel); + if (OpenFlAssets.exists(levelPath, type)) + return levelPath; + } + + levelPath = getLibraryPathForce(file, "shared"); + if (OpenFlAssets.exists(levelPath, type)) + return levelPath; + } + + return getPreloadPath(file); + } + + static public function getLibraryPath(file:String, library = "preload") + { + return if (library == "preload" || library == "default") getPreloadPath(file); else getLibraryPathForce(file, library); + } + + inline static function getLibraryPathForce(file:String, library:String) + { + var returnPath = '$library:assets/$library/$file'; + return returnPath; + } + + inline public static function getPreloadPath(file:String = '') + { + return 'assets/$file'; + } + + inline static public function file(file:String, type:AssetType = TEXT, ?library:String) + { + return getPath(file, type, library); + } + + inline static public function txt(key:String, ?library:String) + { + return getPath('data/$key.txt', TEXT, library); + } + + inline static public function xml(key:String, ?library:String) + { + return getPath('data/$key.xml', TEXT, library); + } + + inline static public function json(key:String, ?library:String) + { + return getPath('data/' + key + '.json', TEXT, library); + } + + inline static public function shaderFragment(key:String, ?library:String) + { + return getPath('shaders/$key.frag', TEXT, library); + } + inline static public function shaderVertex(key:String, ?library:String) + { + return getPath('shaders/$key.vert', TEXT, library); + } + inline static public function lua(key:String, ?library:String) + { + return getPath('$key.lua', TEXT, library); + } + //Video loading (part of it) + static public function video(key:String) + { + #if MODS_ALLOWED + var file:String = modsVideo(key); + if(FileSystem.exists(file)) { + return file; + } + #end + return SUtil.getPath() + 'assets/videos/$key.$VIDEO_EXT'; + } + //Sound loading. + static public function sound(key:String, ?library:String):Sound + { + var sound:Sound = returnSound('sounds', key, library); + return sound; + } + //Random sound loading. + inline static public function soundRandom(key:String, min:Int, max:Int, ?library:String) + { + return sound(key + FlxG.random.int(min, max), library); + } + //Music loading. Loads anything in assets/data/music, OR mods/data/music (if mods are allowed) + inline static public function music(key:String, ?library:String):Sound + { + var file:Sound = returnSound('music', key, library); + return file; + } + //Loads the Voices. Crucial for generateSong + inline static public function voices(song:String):Any + { + #if html5 + return 'songs:assets/songs/${formatToSongPath(song)}/Voices.$SOUND_EXT'; + #else + var songKey:String = '${formatToSongPath(song)}/Voices'; + var voices = returnSound('songs', songKey); + if (!ClientPrefs.progAudioLoad) voices = returnSoundFull('songs', songKey); + return voices; + #end + } + //Loads the instrumental. Crucial for generateSong + inline static public function inst(song:String):Any + { + #if html5 + return 'songs:assets/songs/${formatToSongPath(song)}/Inst.$SOUND_EXT'; + #else + var songKey:String = '${formatToSongPath(song)}/Inst'; + var inst = returnSound('songs', songKey); + if (!ClientPrefs.progAudioLoad) inst = returnSoundFull('songs', songKey); + return inst; + #end + } + +//Difficulty-specific Inst and Voices loading. Doesn't work so i've scrapped it for now but this was taken directly from Leather Engine + /* + static public function voices(song:String, ?difficulty:String) + { + if(difficulty != null) + { + if(Assets.exists('songs:assets/songs/${song.toLowerCase()}/Voices-$difficulty.$SOUND_EXT')) + { + return 'songs:assets/songs/${song.toLowerCase()}/Voices-$difficulty.$SOUND_EXT'; + } + } + + return 'songs:assets/songs/${song.toLowerCase()}/Voices.$SOUND_EXT'; + } + + static public function inst(song:String, ?difficulty:String) + { + if(difficulty != null) + { + if(Assets.exists('songs:assets/songs/${song.toLowerCase()}/Inst-$difficulty.$SOUND_EXT')) + { + return 'songs:assets/songs/${song.toLowerCase()}/Inst-$difficulty.$SOUND_EXT'; + } + } + + return 'songs:assets/songs/${song.toLowerCase()}/Inst.$SOUND_EXT'; + } + */ + //Loads images. + public static var currentTrackedAssets:Map = []; + static public function image(key:String, ?library:String = null, ?allowGPU:Bool = true):FlxGraphic + { + if (ClientPrefs.cacheOnGPU) { + var bitmap:BitmapData = null; + var file:String = null; + + #if MODS_ALLOWED + file = modsImages(key); + if (currentTrackedAssets.exists(file)) + { + localTrackedAssets.push(file); + return currentTrackedAssets.get(file); + } + else if (FileSystem.exists(file)) + bitmap = BitmapData.fromFile(file); + else + #end + { + file = getPath('images/$key.png', IMAGE, library); + if (currentTrackedAssets.exists(file)) + { + localTrackedAssets.push(file); + return currentTrackedAssets.get(file); + } + else if (OpenFlAssets.exists(file, IMAGE)) + bitmap = OpenFlAssets.getBitmapData(file); + } + + if (bitmap != null) + { + localTrackedAssets.push(file); + if (allowGPU && ClientPrefs.cacheOnGPU) + { + var texture:RectangleTexture = FlxG.stage.context3D.createRectangleTexture(bitmap.width, bitmap.height, BGRA, true); + texture.uploadFromBitmapData(bitmap); + bitmap.image.data = null; + bitmap.dispose(); + bitmap.disposeImage(); + bitmap = BitmapData.fromTexture(texture); + } + var newGraphic:FlxGraphic = FlxGraphic.fromBitmapData(bitmap, false, file); + newGraphic.persist = true; + newGraphic.destroyOnNoUse = false; + currentTrackedAssets.set(file, newGraphic); + return newGraphic; + } + + trace('oh no its returning null NOOOO ($file)'); + return null; + } else { + #if MODS_ALLOWED + var modKey:String = modsImages(key); + if(FileSystem.exists(modKey)) { + if(!currentTrackedAssets.exists(modKey)) { + var newBitmap:BitmapData = BitmapData.fromFile(modKey); + var newGraphic:FlxGraphic = FlxGraphic.fromBitmapData(newBitmap, false, modKey); + newGraphic.persist = true; + currentTrackedAssets.set(modKey, newGraphic); + } + localTrackedAssets.push(modKey); + return currentTrackedAssets.get(modKey); + } + #end + + var path = getPath('images/$key.png', IMAGE, library); + //trace(path); + if (OpenFlAssets.exists(path, IMAGE)) { + if(!currentTrackedAssets.exists(path)) { + var newGraphic:FlxGraphic = FlxG.bitmap.add(path, false, path); + newGraphic.persist = true; + currentTrackedAssets.set(path, newGraphic); + } + localTrackedAssets.push(path); + return currentTrackedAssets.get(path); + } + trace('oh no its returning null NOOOO (' + modKey + ')'); + return null; + } + } + + static public function getTextFromFile(key:String, ?ignoreMods:Bool = false):String + { + #if sys + #if MODS_ALLOWED + if (!ignoreMods && FileSystem.exists(modFolders(key))) + return File.getContent(modFolders(key)); + #end + + if (FileSystem.exists(SUtil.getPath() + getPreloadPath(key))) + return File.getContent(SUtil.getPath() + getPreloadPath(key)); + + if (currentLevel != null) + { + var levelPath:String = ''; + if(currentLevel != 'shared') { + levelPath = SUtil.getPath() + getLibraryPathForce(key, currentLevel); + if (FileSystem.exists(levelPath)) + return File.getContent(levelPath); + } + + levelPath = SUtil.getPath() + getLibraryPathForce(key, 'shared'); + if (FileSystem.exists(levelPath)) + return File.getContent(levelPath); + } + #end + return Assets.getText(getPath(key, TEXT)); + } + + inline static public function font(key:String) + { + #if MODS_ALLOWED + var file:String = modsFont(key); + if(FileSystem.exists(file)) { + return file; + } + #end + return SUtil.getPath() + 'assets/fonts/$key'; + } + + public static function fileExists(key:String, type:AssetType, ?ignoreMods:Bool = false, ?library:String) + { + #if MODS_ALLOWED + if(FileSystem.exists(mods(currentModDirectory + '/' + key)) || FileSystem.exists(mods(key))) { + return true; + } + #end + + if(OpenFlAssets.exists(getPath(key, type))) { + return true; + } + return false; + } + + inline static public function getSparrowAtlas(key:String, ?library:String):FlxAtlasFrames + { + #if MODS_ALLOWED + var imageLoaded:FlxGraphic = image(key); + var xmlExists:Bool = false; + if(FileSystem.exists(modsXml(key))) { + xmlExists = true; + } + + return FlxAtlasFrames.fromSparrow((imageLoaded != null ? imageLoaded : image(key, library)), (xmlExists ? File.getContent(modsXml(key)) : file('images/$key.xml', library))); + #else + return FlxAtlasFrames.fromSparrow(image(key, library), file('images/$key.xml', library)); + #end + } + + + inline static public function getPackerAtlas(key:String, ?library:String) + { + #if MODS_ALLOWED + var imageLoaded:FlxGraphic = image(key); + var txtExists:Bool = false; + if(FileSystem.exists(modsTxt(key))) { + txtExists = true; + } + + return FlxAtlasFrames.fromSpriteSheetPacker((imageLoaded != null ? imageLoaded : image(key, library)), (txtExists ? File.getContent(modsTxt(key)) : file('images/$key.txt', library))); + #else + return FlxAtlasFrames.fromSpriteSheetPacker(image(key, library), file('images/$key.txt', library)); + #end + } + + inline static public function formatToSongPath(path:String) { + var invalidChars = ~/[~&\\;:<>#]/; + var hideChars = ~/[.,'"%?!]/; + + var path = invalidChars.split(path.replace(' ', '-')).join("-"); + return hideChars.split(path).join("").toLowerCase(); + } + // completely rewritten asset loading? fuck! + public static var currentTrackedSounds:Map = []; + //Returns sounds which is useful for all the sfx + public static function returnSound(path:String, key:String, ?library:String, stream:Bool = false) { + var sound:Sound = null; + var file:String = null; + + #if MODS_ALLOWED + file = modsSounds(path, key); + if (currentTrackedSounds.exists(file)) { + localTrackedAssets.push(file); + return currentTrackedSounds.get(file); + } else if (FileSystem.exists(file)) { + #if lime_vorbis + if (stream) + sound = Sound.fromAudioBuffer(AudioBuffer.fromVorbisFile(VorbisFile.fromFile(file))); + else + #end + sound = Sound.fromFile(file); + } + else + #end + { + // I hate this so god damn much + var gottenPath:String = getPath('$path/$key.$SOUND_EXT', SOUND, library); + file = gottenPath.substring(gottenPath.indexOf(':') + 1, gottenPath.length); + if (path == 'songs') + gottenPath = 'songs:' + gottenPath; + if (currentTrackedSounds.exists(file)) + { + localTrackedAssets.push(file); + return currentTrackedSounds.get(file); + } + else if (OpenFlAssets.exists(gottenPath, SOUND)) + { + #if lime_vorbis + if (stream) + sound = OpenFlAssets.getMusic(gottenPath); + else + #end + sound = OpenFlAssets.getSound(gottenPath); + } + } + + if (sound != null) + { + localTrackedAssets.push(file); + currentTrackedSounds.set(file, sound); + return sound; + } + + trace('oh no its returning null NOOOO ($file)'); + return null; + } + //Ditto, but returns the full sound instead + public static function returnSoundFull(path:String, key:String, ?library:String) { + #if MODS_ALLOWED + var file:String = modsSounds(path, key); + if(FileSystem.exists(file)) { + if(!currentTrackedSounds.exists(file)) { + currentTrackedSounds.set(file, Sound.fromFile(file)); + } + localTrackedAssets.push(key); + return currentTrackedSounds.get(file); + } + #end + // I hate this so god damn much + var gottenPath:String = getPath('$path/$key.$SOUND_EXT', SOUND, library); + gottenPath = gottenPath.substring(gottenPath.indexOf(':') + 1, gottenPath.length); + // trace(gottenPath); + if(!currentTrackedSounds.exists(gottenPath)) + #if MODS_ALLOWED + currentTrackedSounds.set(gottenPath, Sound.fromFile('./' + gottenPath)); + #else + { + var folder:String = ''; + if(path == 'songs') folder = 'songs:'; + + currentTrackedSounds.set(gottenPath, OpenFlAssets.getSound(folder + getPath('$path/$key.$SOUND_EXT', SOUND, library))); + } + #end + localTrackedAssets.push(gottenPath); + return currentTrackedSounds.get(gottenPath); + } + + #if MODS_ALLOWED + //Loads mods. + inline static public function mods(key:String = '') { + return SUtil.getPath() + 'mods/' + key; + } + //Loads fonts in mods/fonts. + inline static public function modsFont(key:String) { + return modFolders('fonts/' + key); + } + //Loads jsons in mods/data. + inline static public function modsJson(key:String) { + return modFolders('data/' + key + '.json'); + } + //Loads videos in mods/videos. + inline static public function modsVideo(key:String) { + return modFolders('videos/' + key + '.' + VIDEO_EXT); + } + //Loads sounds in mods/sounds. + inline static public function modsSounds(path:String, key:String) { + return modFolders(path + '/' + key + '.' + SOUND_EXT); + } + //Loads images in mods/images. + inline static public function modsImages(key:String) { + return modFolders('images/' + key + '.png'); + } + //Loads xml files in mods/images. + inline static public function modsXml(key:String) { + return modFolders('images/' + key + '.xml'); + } + //Loads txt files in mods/images. + inline static public function modsTxt(key:String) { + return modFolders('images/' + key + '.txt'); + } + + /* Goes unused for now + + inline static public function modsShaderFragment(key:String, ?library:String) + { + return modFolders('shaders/'+key+'.frag'); + } + inline static public function modsShaderVertex(key:String, ?library:String) + { + return modFolders('shaders/'+key+'.vert'); + } + inline static public function modsAchievements(key:String) { + return modFolders('achievements/' + key + '.json'); + }*/ + + static public function modFolders(key:String) { + if(currentModDirectory != null && currentModDirectory.length > 0) { + var fileToCheck:String = mods(currentModDirectory + '/' + key); + if(FileSystem.exists(fileToCheck)) { + return fileToCheck; + } + } + + for(mod in getGlobalMods()){ + var fileToCheck:String = mods(mod + '/' + key); + if(FileSystem.exists(fileToCheck)) + return fileToCheck; + + } + return SUtil.getPath() + 'mods/' + key; + } + + public static var globalMods:Array = []; + + static public function getGlobalMods() + return globalMods; + + static public function pushGlobalMods() // prob a better way to do this but idc + { + globalMods = []; + var path:String = SUtil.getPath() + 'modsList.txt'; + if(FileSystem.exists(path)) + { + var list:Array = CoolUtil.coolTextFile(path); + for (i in list) + { + var dat = i.split("|"); + if (dat[1] == "1") + { + var folder = dat[0]; + var path = Paths.mods(folder + '/pack.json'); + if(FileSystem.exists(path)) { + try{ + var rawJson:String = File.getContent(path); + if(rawJson != null && rawJson.length > 0) { + var stuff:Dynamic = Json.parse(rawJson); + var global:Bool = Reflect.getProperty(stuff, "runsGlobally"); + if(global)globalMods.push(dat[0]); + } + } catch(e:Dynamic){ + trace(e); + } + } + } + } + } + return globalMods; + } + + static public function getModDirectories():Array { + var list:Array = []; + var modsFolder:String = mods(); + if(FileSystem.exists(modsFolder)) { + for (folder in FileSystem.readDirectory(modsFolder)) { + var path = haxe.io.Path.join([modsFolder, folder]); + if (sys.FileSystem.isDirectory(path) && !ignoreModFolders.contains(folder) && !list.contains(folder)) { + list.push(folder); + } + } + } + return list; + } + #end +} diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx index 79cf455d10f..580d4c3a56a 100644 --- a/source/PauseSubState.hx +++ b/source/PauseSubState.hx @@ -1,427 +1,427 @@ -package; - -import Controls.Control; -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.FlxSubState; -import flixel.addons.transition.FlxTransitionableState; -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.input.keyboard.FlxKey; -import flixel.system.FlxSound; -import flixel.text.FlxText; -import flixel.tweens.FlxEase; -import flixel.tweens.FlxTween; -import flixel.util.FlxColor; -import flixel.FlxCamera; -import flixel.util.FlxStringUtil; -import options.OptionsState; -import GameplayChangersSubstate; - -class PauseSubState extends MusicBeatSubstate -{ - var grpMenuShit:FlxTypedGroup; - - var menuItems:Array = []; - var menuItemsOG:Array = ['Resume', 'Restart Song', 'Change Gameplay Settings', 'Change Difficulty', 'Options', 'Exit to menu']; - var difficultyChoices = []; - var curSelected:Int = 0; - - var pauseMusic:FlxSound; - var practiceText:FlxText; - var skipTimeText:FlxText; - var skipTimeTracker:Alphabet; - var curTime:Float = Math.max(0, Conductor.songPosition); - //var botplayText:FlxText; - public static var botplayLockout:Bool = false; - public static var inPause:Bool = false; - public static var requireRestart:Bool = false; - - public static var songName:String = ''; - - public function new(x:Float, y:Float) - { - super(); - if(CoolUtil.difficulties.length < 2) menuItemsOG.remove('Change Difficulty'); //No need to change difficulty if there is only one! - if(botplayLockout) menuItemsOG.remove('Toggle Botplay'); //you cant toggle it on MWAHAHAHAHAHA - - if(PlayState.chartingMode) - { - menuItemsOG.insert(2, 'Leave Charting Mode'); - - var num:Int = 0; - if(!PlayState.instance.startingSong) - { - num = 1; - menuItemsOG.insert(3, 'Skip Time'); - } - menuItemsOG.insert(3 + num, 'End Song'); - menuItemsOG.insert(4 + num, 'Toggle Practice Mode'); - menuItemsOG.insert(5 + num, 'Toggle Botplay'); - } - menuItems = menuItemsOG; - - for (i in 0...CoolUtil.difficulties.length) { - var diff:String = '' + CoolUtil.difficulties[i]; - difficultyChoices.push(diff); - } - difficultyChoices.push('BACK'); - - - pauseMusic = new FlxSound(); - if(songName != null) { - pauseMusic.loadEmbedded(Paths.music(songName), true, true); - } else if (songName != 'None') { - pauseMusic.loadEmbedded(Paths.music(Paths.formatToSongPath(ClientPrefs.pauseMusic)), true, true); - } - pauseMusic.volume = 0; - pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2))); - - FlxG.sound.list.add(pauseMusic); - - var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - bg.alpha = 0; - bg.scrollFactor.set(); - add(bg); - - var levelInfo:FlxText = new FlxText(20, 15, 0, "", 32); - levelInfo.text += PlayState.SONG.song; - levelInfo.scrollFactor.set(); - levelInfo.setFormat(Paths.font("vcr.ttf"), 32); - levelInfo.updateHitbox(); - add(levelInfo); - - var levelDifficulty:FlxText = new FlxText(20, 15 + 32, 0, "", 32); - levelDifficulty.text += CoolUtil.difficultyString(); - levelDifficulty.scrollFactor.set(); - levelDifficulty.setFormat(Paths.font('vcr.ttf'), 32); - levelDifficulty.updateHitbox(); - add(levelDifficulty); - - var blueballedTxt:FlxText = new FlxText(20, 15 + 64, 0, "", 32); - blueballedTxt.text = "Blueballed: " + PlayState.deathCounter; - blueballedTxt.scrollFactor.set(); - blueballedTxt.setFormat(Paths.font('vcr.ttf'), 32); - blueballedTxt.updateHitbox(); - add(blueballedTxt); - - practiceText = new FlxText(20, 15 + 101, 0, "PRACTICE MODE", 32); - practiceText.scrollFactor.set(); - practiceText.setFormat(Paths.font('vcr.ttf'), 32); - practiceText.x = FlxG.width - (practiceText.width + 20); - practiceText.updateHitbox(); - practiceText.visible = PlayState.instance.practiceMode; - add(practiceText); - - var chartingText:FlxText = new FlxText(20, 15 + 101, 0, "CHARTING MODE", 32); - chartingText.scrollFactor.set(); - chartingText.setFormat(Paths.font('vcr.ttf'), 32); - chartingText.x = FlxG.width - (chartingText.width + 20); - chartingText.y = FlxG.height - (chartingText.height + 20); - chartingText.updateHitbox(); - chartingText.visible = PlayState.chartingMode; - add(chartingText); - - blueballedTxt.alpha = 0; - levelDifficulty.alpha = 0; - levelInfo.alpha = 0; - - levelInfo.x = FlxG.width - (levelInfo.width + 20); - levelDifficulty.x = FlxG.width - (levelDifficulty.width + 20); - blueballedTxt.x = FlxG.width - (blueballedTxt.width + 20); - - FlxTween.tween(bg, {alpha: 0.6}, 0.4, {ease: FlxEase.quartInOut}); - FlxTween.tween(levelInfo, {alpha: 1, y: 20}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.3}); - FlxTween.tween(levelDifficulty, {alpha: 1, y: levelDifficulty.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.5}); - FlxTween.tween(blueballedTxt, {alpha: 1, y: blueballedTxt.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.7}); - - grpMenuShit = new FlxTypedGroup(); - add(grpMenuShit); - - regenMenu(); - cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; - - #if android - PlayState.chartingMode ? addVirtualPad(LEFT_FULL, A) : addVirtualPad(UP_DOWN, A); - addPadCamera(); - #end - } - - var holdTime:Float = 0; - var cantUnpause:Float = 0.1; - override function update(elapsed:Float) - { - if(requireRestart) { - menuItemsOG.remove('Resume'); //technically that's the logical thing to do - regenMenu(); - requireRestart = false; - } - cantUnpause -= elapsed; - if (pauseMusic.volume < 0.5) - pauseMusic.volume += 0.01 * elapsed; - - super.update(elapsed); - updateSkipTextStuff(); - - var upP = controls.UI_UP_P; - var downP = controls.UI_DOWN_P; - var accepted = controls.ACCEPT; - - if (upP) - { - changeSelection(-1); - } - if (downP) - { - changeSelection(1); - } - - var daSelected:String = menuItems[curSelected]; - switch (daSelected) - { - case 'Skip Time': - if (controls.UI_LEFT_P) - { - FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); - curTime -= 1000; - holdTime = 0; - } - if (controls.UI_RIGHT_P) - { - FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); - curTime += 1000; - holdTime = 0; - } - - if(controls.UI_LEFT || controls.UI_RIGHT) - { - holdTime += elapsed; - if(holdTime > 0.5) - { - curTime += 45000 * elapsed * (controls.UI_LEFT ? -1 : 1); - } - if(holdTime > 0.5 && FlxG.sound.music.length >= 600000) - { - curTime += 150000 * elapsed * (controls.UI_LEFT ? -1 : 1); - } - if(holdTime > 0.5 && FlxG.sound.music.length >= 3600000 || PlayState.SONG.song.toLowerCase() == 'desert bus' && holdTime > 0.5) - { - curTime += 450000 * elapsed * (controls.UI_LEFT ? -1 : 1); - } - - if(curTime >= FlxG.sound.music.length || PlayState.SONG.song.toLowerCase() == 'desert bus' && curTime >= 28820000) curTime -= FlxG.sound.music.length; - else if(curTime < 0) curTime += FlxG.sound.music.length; - updateSkipTimeText(); - } - } - - if (accepted && (cantUnpause <= 0 || !ClientPrefs.controllerMode)) - { - if (menuItems == difficultyChoices) - { - if(menuItems.length - 1 != curSelected && difficultyChoices.contains(daSelected)) { - var name:String = PlayState.SONG.song; - var poop = Highscore.formatSong(name, curSelected); - PlayState.SONG = Song.loadFromJson(poop, name); - PlayState.storyDifficulty = curSelected; - MusicBeatState.resetState(); - FlxG.sound.music.volume = 0; - PlayState.changedDifficulty = true; - PlayState.chartingMode = false; - return; - } - - menuItems = menuItemsOG; - regenMenu(); - } - - switch (daSelected) - { - case "Resume": - close(); - case 'Change Difficulty': - menuItems = difficultyChoices; - deleteSkipTimeText(); - regenMenu(); - case 'Toggle Practice Mode': - PlayState.instance.practiceMode = !PlayState.instance.practiceMode; - PlayState.changedDifficulty = true; - practiceText.visible = PlayState.instance.practiceMode; - case "Restart Song": - restartSong(); - case "Leave Charting Mode": - restartSong(); - PlayState.chartingMode = false; - case 'Skip Time': - if(curTime < Conductor.songPosition) - { - PlayState.startOnTime = curTime; - restartSong(true); - } - else - { - if (curTime != Conductor.songPosition) - { - PlayState.instance.clearNotesBefore(curTime); - PlayState.instance.setSongTime(curTime); - } - close(); - } - case "End Song": - close(); - PlayState.instance.finishSong(true); - case "Change Gameplay Settings": - persistentUpdate = false; - openSubState(new GameplayChangersSubstate()); - GameplayChangersSubstate.inThePauseMenu = true; - case 'Toggle Botplay': - PlayState.instance.cpuControlled = !PlayState.instance.cpuControlled; - PlayState.changedDifficulty = true; - if (PlayState.instance.botplayTxt != null) - { - PlayState.instance.botplayTxt.visible = PlayState.instance.cpuControlled; - PlayState.instance.botplayTxt.alpha = 1; - PlayState.instance.botplaySine = 0; - } - case "Options": - MusicBeatState.switchState(new OptionsState()); - inPause = true; - if(ClientPrefs.pauseMusic != 'None') - { - FlxG.sound.playMusic(Paths.music(Paths.formatToSongPath(ClientPrefs.pauseMusic)), pauseMusic.volume); - FlxTween.tween(FlxG.sound.music, {volume: 1}, 0.8); - FlxG.sound.music.time = pauseMusic.time; - } - case "Exit to menu": - PlayState.deathCounter = 0; - PlayState.seenCutscene = false; - - WeekData.loadTheFirstEnabledMod(); - if(PlayState.isStoryMode) { - MusicBeatState.switchState(new StoryMenuState()); - } else { - MusicBeatState.switchState(new FreeplayState()); - } - PlayState.cancelMusicFadeTween(); - FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic)); - PlayState.changedDifficulty = false; - PlayState.chartingMode = false; - } - } - } - - function deleteSkipTimeText() - { - if(skipTimeText != null) - { - skipTimeText.kill(); - remove(skipTimeText); - skipTimeText.destroy(); - } - skipTimeText = null; - skipTimeTracker = null; - } - - public static function restartSong(noTrans:Bool = false) - { - PlayState.instance.paused = true; // For lua - FlxG.sound.music.volume = 0; - PlayState.instance.vocals.volume = 0; - - if(noTrans) - { - FlxTransitionableState.skipNextTransOut = true; - FlxG.resetState(); - } - else - { - MusicBeatState.resetState(); - } - } - - override function destroy() - { - pauseMusic.destroy(); - - super.destroy(); - } - - function changeSelection(change:Int = 0):Void - { - curSelected += change; - - FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); - - if (curSelected < 0) - curSelected = menuItems.length - 1; - if (curSelected >= menuItems.length) - curSelected = 0; - - var bullShit:Int = 0; - - for (item in grpMenuShit.members) - { - item.targetY = bullShit - curSelected; - bullShit++; - - item.alpha = 0.6; - // item.setGraphicSize(Std.int(item.width * 0.8)); - - if (item.targetY == 0) - { - item.alpha = 1; - // item.setGraphicSize(Std.int(item.width)); - - if(item == skipTimeTracker) - { - curTime = Math.max(0, Conductor.songPosition); - updateSkipTimeText(); - } - } - } - } - - public function regenMenu():Void { - for (i in 0...grpMenuShit.members.length) { - var obj = grpMenuShit.members[0]; - obj.kill(); - grpMenuShit.remove(obj, true); - obj.destroy(); - } - - for (i in 0...menuItems.length) { - var item = new Alphabet(90, 320, menuItems[i], true); - item.isMenuItem = true; - item.targetY = i; - grpMenuShit.add(item); - - if(menuItems[i] == 'Skip Time') - { - skipTimeText = new FlxText(0, 0, 0, '', 64); - skipTimeText.setFormat(Paths.font("vcr.ttf"), 64, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - skipTimeText.scrollFactor.set(); - skipTimeText.borderSize = 2; - skipTimeTracker = item; - add(skipTimeText); - - updateSkipTextStuff(); - updateSkipTimeText(); - } - } - curSelected = 0; - changeSelection(); - } - - function updateSkipTextStuff() - { - if(skipTimeText == null || skipTimeTracker == null) return; - - skipTimeText.x = skipTimeTracker.x + skipTimeTracker.width + 60; - skipTimeText.y = skipTimeTracker.y; - skipTimeText.visible = (skipTimeTracker.alpha >= 1); - } - - function updateSkipTimeText() - { - skipTimeText.text = FlxStringUtil.formatTime(Math.max(0, Math.floor(curTime / 1000)), false) + ' / ' + FlxStringUtil.formatTime(Math.max(0, Math.floor(FlxG.sound.music.length / 1000)), false); - } +package; + +import Controls.Control; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.FlxSubState; +import flixel.addons.transition.FlxTransitionableState; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.input.keyboard.FlxKey; +import flixel.system.FlxSound; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; +import flixel.FlxCamera; +import flixel.util.FlxStringUtil; +import options.OptionsState; +import GameplayChangersSubstate; + +class PauseSubState extends MusicBeatSubstate +{ + var grpMenuShit:FlxTypedGroup; + + var menuItems:Array = []; + var menuItemsOG:Array = ['Resume', 'Restart Song', 'Change Gameplay Settings', 'Change Difficulty', 'Options', 'Exit to menu']; + var difficultyChoices = []; + var curSelected:Int = 0; + + var pauseMusic:FlxSound; + var practiceText:FlxText; + var skipTimeText:FlxText; + var skipTimeTracker:Alphabet; + var curTime:Float = Math.max(0, Conductor.songPosition); + //var botplayText:FlxText; + public static var botplayLockout:Bool = false; + public static var inPause:Bool = false; + public static var requireRestart:Bool = false; + + public static var songName:String = ''; + + public function new(x:Float, y:Float) + { + super(); + if(CoolUtil.difficulties.length < 2) menuItemsOG.remove('Change Difficulty'); //No need to change difficulty if there is only one! + if(botplayLockout) menuItemsOG.remove('Toggle Botplay'); //you cant toggle it on MWAHAHAHAHAHA + + if(PlayState.chartingMode) + { + menuItemsOG.insert(2, 'Leave Charting Mode'); + + var num:Int = 0; + if(!PlayState.instance.startingSong) + { + num = 1; + menuItemsOG.insert(3, 'Skip Time'); + } + menuItemsOG.insert(3 + num, 'End Song'); + menuItemsOG.insert(4 + num, 'Toggle Practice Mode'); + menuItemsOG.insert(5 + num, 'Toggle Botplay'); + } + menuItems = menuItemsOG; + + for (i in 0...CoolUtil.difficulties.length) { + var diff:String = '' + CoolUtil.difficulties[i]; + difficultyChoices.push(diff); + } + difficultyChoices.push('BACK'); + + + pauseMusic = new FlxSound(); + if(songName != null) { + pauseMusic.loadEmbedded(Paths.music(songName), true, true); + } else if (songName != 'None') { + pauseMusic.loadEmbedded(Paths.music(Paths.formatToSongPath(ClientPrefs.pauseMusic)), true, true); + } + pauseMusic.volume = 0; + pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2))); + + FlxG.sound.list.add(pauseMusic); + + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + bg.alpha = 0; + bg.scrollFactor.set(); + add(bg); + + var levelInfo:FlxText = new FlxText(20, 15, 0, "", 32); + levelInfo.text += PlayState.SONG.song; + levelInfo.scrollFactor.set(); + levelInfo.setFormat(Paths.font("vcr.ttf"), 32); + levelInfo.updateHitbox(); + add(levelInfo); + + var levelDifficulty:FlxText = new FlxText(20, 15 + 32, 0, "", 32); + levelDifficulty.text += CoolUtil.difficultyString(); + levelDifficulty.scrollFactor.set(); + levelDifficulty.setFormat(Paths.font('vcr.ttf'), 32); + levelDifficulty.updateHitbox(); + add(levelDifficulty); + + var blueballedTxt:FlxText = new FlxText(20, 15 + 64, 0, "", 32); + blueballedTxt.text = "Blueballed: " + PlayState.deathCounter; + blueballedTxt.scrollFactor.set(); + blueballedTxt.setFormat(Paths.font('vcr.ttf'), 32); + blueballedTxt.updateHitbox(); + add(blueballedTxt); + + practiceText = new FlxText(20, 15 + 101, 0, "PRACTICE MODE", 32); + practiceText.scrollFactor.set(); + practiceText.setFormat(Paths.font('vcr.ttf'), 32); + practiceText.x = FlxG.width - (practiceText.width + 20); + practiceText.updateHitbox(); + practiceText.visible = PlayState.instance.practiceMode; + add(practiceText); + + var chartingText:FlxText = new FlxText(20, 15 + 101, 0, "CHARTING MODE", 32); + chartingText.scrollFactor.set(); + chartingText.setFormat(Paths.font('vcr.ttf'), 32); + chartingText.x = FlxG.width - (chartingText.width + 20); + chartingText.y = FlxG.height - (chartingText.height + 20); + chartingText.updateHitbox(); + chartingText.visible = PlayState.chartingMode; + add(chartingText); + + blueballedTxt.alpha = 0; + levelDifficulty.alpha = 0; + levelInfo.alpha = 0; + + levelInfo.x = FlxG.width - (levelInfo.width + 20); + levelDifficulty.x = FlxG.width - (levelDifficulty.width + 20); + blueballedTxt.x = FlxG.width - (blueballedTxt.width + 20); + + FlxTween.tween(bg, {alpha: 0.6}, 0.4, {ease: FlxEase.quartInOut}); + FlxTween.tween(levelInfo, {alpha: 1, y: 20}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.3}); + FlxTween.tween(levelDifficulty, {alpha: 1, y: levelDifficulty.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.5}); + FlxTween.tween(blueballedTxt, {alpha: 1, y: blueballedTxt.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.7}); + + grpMenuShit = new FlxTypedGroup(); + add(grpMenuShit); + + regenMenu(); + cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; + + #if android + PlayState.chartingMode ? addVirtualPad(LEFT_FULL, A) : addVirtualPad(UP_DOWN, A); + addPadCamera(); + #end + } + + var holdTime:Float = 0; + var cantUnpause:Float = 0.1; + override function update(elapsed:Float) + { + if(requireRestart) { + menuItemsOG.remove('Resume'); //technically that's the logical thing to do + regenMenu(); + requireRestart = false; + } + cantUnpause -= elapsed; + if (pauseMusic.volume < 0.5) + pauseMusic.volume += 0.01 * elapsed; + + super.update(elapsed); + updateSkipTextStuff(); + + var upP = controls.UI_UP_P; + var downP = controls.UI_DOWN_P; + var accepted = controls.ACCEPT; + + if (upP) + { + changeSelection(-1); + } + if (downP) + { + changeSelection(1); + } + + var daSelected:String = menuItems[curSelected]; + switch (daSelected) + { + case 'Skip Time': + if (controls.UI_LEFT_P) + { + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + curTime -= 1000; + holdTime = 0; + } + if (controls.UI_RIGHT_P) + { + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + curTime += 1000; + holdTime = 0; + } + + if(controls.UI_LEFT || controls.UI_RIGHT) + { + holdTime += elapsed; + if(holdTime > 0.5) + { + curTime += 45000 * elapsed * (controls.UI_LEFT ? -1 : 1); + } + if(holdTime > 0.5 && FlxG.sound.music.length >= 600000) + { + curTime += 150000 * elapsed * (controls.UI_LEFT ? -1 : 1); + } + if(holdTime > 0.5 && FlxG.sound.music.length >= 3600000 || PlayState.SONG.song.toLowerCase() == 'desert bus' && holdTime > 0.5) + { + curTime += 450000 * elapsed * (controls.UI_LEFT ? -1 : 1); + } + + if(curTime >= FlxG.sound.music.length || PlayState.SONG.song.toLowerCase() == 'desert bus' && curTime >= 28820000) curTime -= FlxG.sound.music.length; + else if(curTime < 0) curTime += FlxG.sound.music.length; + updateSkipTimeText(); + } + } + + if (accepted && (cantUnpause <= 0 || !ClientPrefs.controllerMode)) + { + if (menuItems == difficultyChoices) + { + if(menuItems.length - 1 != curSelected && difficultyChoices.contains(daSelected)) { + var name:String = PlayState.SONG.song; + var poop = Highscore.formatSong(name, curSelected); + PlayState.SONG = Song.loadFromJson(poop, name); + PlayState.storyDifficulty = curSelected; + MusicBeatState.resetState(); + FlxG.sound.music.volume = 0; + PlayState.changedDifficulty = true; + PlayState.chartingMode = false; + return; + } + + menuItems = menuItemsOG; + regenMenu(); + } + + switch (daSelected) + { + case "Resume": + close(); + case 'Change Difficulty': + menuItems = difficultyChoices; + deleteSkipTimeText(); + regenMenu(); + case 'Toggle Practice Mode': + PlayState.instance.practiceMode = !PlayState.instance.practiceMode; + PlayState.changedDifficulty = true; + practiceText.visible = PlayState.instance.practiceMode; + case "Restart Song": + restartSong(); + case "Leave Charting Mode": + restartSong(); + PlayState.chartingMode = false; + case 'Skip Time': + if(curTime < Conductor.songPosition) + { + PlayState.startOnTime = curTime; + restartSong(true); + } + else + { + if (curTime != Conductor.songPosition) + { + PlayState.instance.clearNotesBefore(curTime); + PlayState.instance.setSongTime(curTime); + } + close(); + } + case "End Song": + close(); + PlayState.instance.finishSong(true); + case "Change Gameplay Settings": + persistentUpdate = false; + openSubState(new GameplayChangersSubstate()); + GameplayChangersSubstate.inThePauseMenu = true; + case 'Toggle Botplay': + PlayState.instance.cpuControlled = !PlayState.instance.cpuControlled; + PlayState.changedDifficulty = true; + if (PlayState.instance.botplayTxt != null) + { + PlayState.instance.botplayTxt.visible = PlayState.instance.cpuControlled; + PlayState.instance.botplayTxt.alpha = 1; + PlayState.instance.botplaySine = 0; + } + case "Options": + MusicBeatState.switchState(new OptionsState()); + inPause = true; + if(ClientPrefs.pauseMusic != 'None') + { + FlxG.sound.playMusic(Paths.music(Paths.formatToSongPath(ClientPrefs.pauseMusic)), pauseMusic.volume); + FlxTween.tween(FlxG.sound.music, {volume: 1}, 0.8); + FlxG.sound.music.time = pauseMusic.time; + } + case "Exit to menu": + PlayState.deathCounter = 0; + PlayState.seenCutscene = false; + + WeekData.loadTheFirstEnabledMod(); + if(PlayState.isStoryMode) { + MusicBeatState.switchState(new StoryMenuState()); + } else { + MusicBeatState.switchState(new FreeplayState()); + } + PlayState.cancelMusicFadeTween(); + FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic)); + PlayState.changedDifficulty = false; + PlayState.chartingMode = false; + } + } + } + + function deleteSkipTimeText() + { + if(skipTimeText != null) + { + skipTimeText.kill(); + remove(skipTimeText); + skipTimeText.destroy(); + } + skipTimeText = null; + skipTimeTracker = null; + } + + public static function restartSong(noTrans:Bool = false) + { + PlayState.instance.paused = true; // For lua + FlxG.sound.music.volume = 0; + PlayState.instance.vocals.volume = 0; + + if(noTrans) + { + FlxTransitionableState.skipNextTransOut = true; + FlxG.resetState(); + } + else + { + MusicBeatState.resetState(); + } + } + + override function destroy() + { + pauseMusic.destroy(); + + super.destroy(); + } + + function changeSelection(change:Int = 0):Void + { + curSelected += change; + + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + + if (curSelected < 0) + curSelected = menuItems.length - 1; + if (curSelected >= menuItems.length) + curSelected = 0; + + var bullShit:Int = 0; + + for (item in grpMenuShit.members) + { + item.targetY = bullShit - curSelected; + bullShit++; + + item.alpha = 0.6; + // item.setGraphicSize(Std.int(item.width * 0.8)); + + if (item.targetY == 0) + { + item.alpha = 1; + // item.setGraphicSize(Std.int(item.width)); + + if(item == skipTimeTracker) + { + curTime = Math.max(0, Conductor.songPosition); + updateSkipTimeText(); + } + } + } + } + + public function regenMenu():Void { + for (i in 0...grpMenuShit.members.length) { + var obj = grpMenuShit.members[0]; + obj.kill(); + grpMenuShit.remove(obj, true); + obj.destroy(); + } + + for (i in 0...menuItems.length) { + var item = new Alphabet(90, 320, menuItems[i], true); + item.isMenuItem = true; + item.targetY = i; + grpMenuShit.add(item); + + if(menuItems[i] == 'Skip Time') + { + skipTimeText = new FlxText(0, 0, 0, '', 64); + skipTimeText.setFormat(Paths.font("vcr.ttf"), 64, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + skipTimeText.scrollFactor.set(); + skipTimeText.borderSize = 2; + skipTimeTracker = item; + add(skipTimeText); + + updateSkipTextStuff(); + updateSkipTimeText(); + } + } + curSelected = 0; + changeSelection(); + } + + function updateSkipTextStuff() + { + if(skipTimeText == null || skipTimeTracker == null) return; + + skipTimeText.x = skipTimeTracker.x + skipTimeTracker.width + 60; + skipTimeText.y = skipTimeTracker.y; + skipTimeText.visible = (skipTimeTracker.alpha >= 1); + } + + function updateSkipTimeText() + { + skipTimeText.text = FlxStringUtil.formatTime(Math.max(0, Math.floor(curTime / 1000)), false) + ' / ' + FlxStringUtil.formatTime(Math.max(0, Math.floor(FlxG.sound.music.length / 1000)), false); + } } \ No newline at end of file diff --git a/source/PlayState.hx b/source/PlayState.hx index a58afec4a8a..4007b68ca08 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -1,9834 +1,9871 @@ -package; - -import flixel.graphics.FlxGraphic; -#if desktop -import Discord.DiscordClient; -#end -import Section.SwagSection; -import Song.SwagSong; -import WiggleEffect.WiggleEffectType; -import flixel.FlxBasic; -import flixel.FlxCamera; -import flixel.FlxG; -import flixel.FlxGame; -import flixel.FlxObject; -import flixel.FlxSprite; -import flixel.FlxState; -import flixel.FlxSubState; -import flixel.addons.display.FlxGridOverlay; -import flixel.addons.effects.FlxTrail; -import flixel.addons.effects.FlxTrailArea; -import flixel.addons.effects.chainable.FlxEffectSprite; -import flixel.addons.effects.chainable.FlxWaveEffect; -import flixel.addons.transition.FlxTransitionableState; -import flixel.graphics.atlas.FlxAtlas; -import flixel.graphics.frames.FlxAtlasFrames; -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.math.FlxMath; -import flixel.math.FlxPoint; -import flixel.math.FlxRect; -import flixel.system.FlxSound; -import flixel.text.FlxText; -import flixel.tweens.FlxEase; -import flixel.tweens.FlxTween; -import flixel.ui.FlxBar; -import flixel.util.FlxCollision; -import flixel.util.FlxColor; -import flixel.util.FlxSort; -import flixel.util.FlxStringUtil; -import flixel.util.FlxTimer; -import haxe.Json; -import haxe.Int64; -import lime.utils.Assets; -import openfl.Lib; -import openfl.filters.BitmapFilter; -import openfl.display.BlendMode; -import openfl.display.StageQuality; -import openfl.filters.BitmapFilter; -import openfl.utils.Assets as OpenFlAssets; -import editors.ChartingState; -import editors.CharacterEditorState; -import flixel.group.FlxSpriteGroup; -import flixel.input.keyboard.FlxKey; -import Note.EventNote; -import openfl.events.KeyboardEvent; -import flixel.effects.particles.FlxEmitter; -import flixel.effects.particles.FlxParticle; -import flixel.util.FlxSave; -import flixel.animation.FlxAnimationController; -import animateatlas.AtlasFrameMaker; -import Achievements; -import StageData; -import FunkinLua; -import DialogueBoxPsych; -import Conductor.Rating; -import Shaders; -import flixel.util.FlxPool; - - -#if !flash -import flixel.addons.display.FlxRuntimeShader; -import openfl.filters.ShaderFilter; -#end - -#if sys -import sys.FileSystem; -import sys.io.File; -#end - -#if VIDEOS_ALLOWED -#if (hxCodec >= "3.0.0") -import hxcodec.flixel.FlxVideo as MP4Handler; -#elseif (hxCodec == "2.6.1") -import hxcodec.VideoHandler as MP4Handler; -#elseif (hxCodec == "2.6.0") -import VideoHandler as MP4Handler; -#else -import vlc.MP4Handler; -#end -#end - -import ColorSwap.ColorSwapShader; //for motion blur - - -using StringTools; - -class PlayState extends MusicBeatState -{ - var noteRows:Array>> = [[],[]]; - private var singAnimations:Array = ['singLEFT', 'singDOWN', 'singUP', 'singRIGHT']; - - public static var instance:PlayState; - public static var STRUM_X = 48.5; - public static var STRUM_X_MIDDLESCROLL = -278; - - public static var ratingStuff:Array = []; - - - private var tauntKey:Array; - - public var shader_chromatic_abberation:ChromaticAberrationEffect; - public var camGameShaders:Array = []; - public var camHUDShaders:Array = []; - public var camOtherShaders:Array = []; - - //event variables - private var isCameraOnForcedPos:Bool = false; - - #if (haxe >= "4.0.0") - public var boyfriendMap:Map = new Map(); - public var dadMap:Map = new Map(); - public var gfMap:Map = new Map(); - public var variables:Map = new Map(); - public var modchartTweens:Map = new Map(); - public var modchartSprites:Map = new Map(); - public var modchartTimers:Map = new Map(); - public var modchartSounds:Map = new Map(); - public var modchartTexts:Map = new Map(); - public var modchartSaves:Map = new Map(); - #else - public var boyfriendMap:Map = new Map(); - public var dadMap:Map = new Map(); - public var gfMap:Map = new Map(); - public var variables:Map = new Map(); - public var modchartTweens:Map = new Map(); - public var modchartSprites:Map = new Map(); - public var modchartTimers:Map = new Map(); - public var modchartSounds:Map = new Map(); - public var modchartTexts:Map = new Map(); - public var modchartSaves:Map = new Map(); - #end - - public var hitSoundString:String = ClientPrefs.hitsoundType; - - public var BF_X:Float = 770; - public var BF_Y:Float = 100; - public var DAD_X:Float = 100; - public var DAD_Y:Float = 100; - public var GF_X:Float = 400; - public var GF_Y:Float = 130; - - var randomBotplayText:String; - - public var songSpeedTween:FlxTween; - public var songSpeed(default, set):Float = 1; - public var songSpeedType:String = "multiplicative"; - - public var noteKillOffset:Float = 350; - - public var playbackRate(default, set):Float = 1; - - public var boyfriendGroup:FlxSpriteGroup; - public var dadGroup:FlxSpriteGroup; - public var gfGroup:FlxSpriteGroup; - public var shaderUpdates:ArrayVoid> = []; - var botplayUsed:Bool = false; - public static var curStage:String = ''; - public static var isPixelStage:Bool = false; - public static var SONG:SwagSong = null; - public static var isStoryMode:Bool = false; - public static var storyWeek:Int = 0; - public static var storyPlaylist:Array = []; - public static var storyDifficulty:Int = 1; - public var tries:Int = 0; - public var notesLoadedRN:Int = 0; - public var firstNoteStrumTime:Float = 0; - - public var spawnTime:Float = 1800; //just enough for the notes to barely inch off the screen - - public var vocals:FlxSound; - public var dadGhostTween:FlxTween; - public var bfGhostTween:FlxTween; - public var gfGhostTween:FlxTween; - public var dadGhost:FlxSprite; - public var bfGhost:FlxSprite; - public var gfGhost:FlxSprite; - public var dad:Character = null; - public var gf:Character = null; - public var boyfriend:Boyfriend = null; - public static var death:FlxSprite; - public static var deathanim:Bool = false; - public static var dead:Bool = false; - - var tankmanAscend:Bool = false; // funni (2021 nostalgia oh my god) - - public var notes:FlxTypedGroup; - public var unspawnNotes:Array = []; - public var unspawnNotesCopy:Array = []; - public var eventNotes:Array = []; - - private var strumLine:FlxSprite; - - //Handles the new epic mega sexy cam code that i've done - public var camFollow:FlxPoint; - public var camFollowPos:FlxObject; - private static var prevCamFollow:FlxPoint; - private static var prevCamFollowPos:FlxObject; - public var judgeColours:Map = [ - "marv" => 0xFFE367E5, - "sick" => FlxColor.CYAN, - "good" => FlxColor.LIME, - "bad" => FlxColor.ORANGE, - "shit" => FlxColor.RED, - "miss" => 0xFF7F2626 - ]; - public var tgtJudgeColours:Map = [ - "marv" => 0xFFE367E5, - "sick" => 0xFF00A2E8, - "good" => 0xFFB5E61D, - "bad" => 0xFFC3C3C3, - "shit" => 0xFF7F7F7F, - "miss" => 0xFF7F2626, - "cb" => 0xFF7F265A - ]; - - public var strumLineNotes:FlxTypedGroup; - public var opponentStrums:FlxTypedGroup; - public var playerStrums:FlxTypedGroup; - public var grpNoteSplashes:FlxTypedGroup; - public var laneunderlay:FlxSprite; - public var laneunderlayOpponent:FlxSprite; - - public var camZooming:Bool = false; - public var camZoomingMult:Float = 1; - public var camZoomingDecay:Float = 1; - private var curSong:String = ""; - - public var gfSpeed:Int = 1; - public var health:Float; - private var displayedHealth:Float; - public var maxHealth:Float = 2; - - - public var totalNotesPlayed:Float = 0; - public var combo:Float = 0; - public var maxCombo:Float = 0; - public var missCombo:Int = 0; - - public var notesAddedCount:Int = 0; - - var endingTimeLimit:Int = 20; - - var camBopInterval:Int = 4; - var camBopIntensity:Float = 1; - - private var healthBarBG:AttachedSprite; - public var healthBar:FlxBar; - var songPercent:Float = 0; - var songPercentThing:Float = 0; - var playbackRateDecimal:Float = 0; - - private var timeBarBG:AttachedSprite; - public var timeBar:FlxBar; - - public var ratingsData:Array = []; - public var marvs:Int = 0; - public var sicks:Int = 0; - public var goods:Int = 0; - public var bads:Int = 0; - public var shits:Int = 0; - public var nps:Float = 0; - public var maxNPS:Float = 0; - public var oppNPS:Float = 0; - public var maxOppNPS:Float = 0; - public var enemyHits:Float = 0; - public var opponentNoteTotal:Int = 0; - public var polyphony:Float = 1; - public var comboMultiplier:Float = 1; - private var allSicks:Bool = true; - - private var lerpingScore:Bool = false; - - private var generatedMusic:Bool = false; - public var endingSong:Bool = false; - public var startingSong:Bool = false; - private var updateTime:Bool = true; - private var updateThePercent:Bool = true; - public static var changedDifficulty:Bool = false; - public static var chartingMode:Bool = false; - public static var playerIsCheating:Bool = false; //Whether the player is cheating. Enables if you change BOTPLAY or Practice Mode in the Pause menu - - public var shownScore:Float = 0; - - //Gameplay settings - public var healthGain:Float = 1; - public var healthLoss:Float = 1; - public var hpDrainLevel:Float = 1; - public var instakillOnMiss:Bool = false; - public var sickOnly:Bool = false; - public var cpuControlled:Bool = false; - public var practiceMode:Bool = false; - public var opponentDrain:Bool = false; - public static var opponentChart:Bool = false; - public static var bothsides:Bool = false; - var randomMode:Bool = false; - var flip:Bool = false; - var stairs:Bool = false; - var waves:Bool = false; - var oneK:Bool = false; - var randomSpeedThing:Bool = false; - var trollingMode:Bool = false; - public var jackingtime:Float = 0; - - public var songWasLooped:Bool = false; //If the song was looped. Used in Troll Mode - public var shouldKillNotes:Bool = true; //Whether notes should be killed when you hit them. Disables automatically when in Troll Mode because you can't end the song anyway - - public var botplaySine:Float = 0; - public var botplayTxt:FlxText; - public var pauseWarnText:FlxText; - - public var OptimHitText:FlxText; - - public var iconP1:HealthIcon; - public var iconP2:HealthIcon; - public var camHUD:FlxCamera; - public var camGame:FlxCamera; - public var camOther:FlxCamera; - public var cameraSpeed:Float = 1; - var hueh231:FlxSprite; - var secretsong:FlxSprite; - var SPUNCHBOB:FlxSprite; - - public var scoreTxtUpdateFrame:Int = 0; - public var judgeCountUpdateFrame:Int = 0; - public var compactUpdateFrame:Int = 0; - - var notesHitArray:Array = []; - var oppNotesHitArray:Array = []; - var notesHitDateArray:Array = []; - var oppNotesHitDateArray:Array = []; - - var dialogue:Array = ['blah blah blah', 'coolswag']; - var dialogueJson:DialogueFile = null; - - var EngineWatermark:FlxText; - var dadbattleBlack:BGSprite; - var dadbattleLight:BGSprite; - var dadbattleSmokes:FlxSpriteGroup; - - var halloweenBG:BGSprite; - var halloweenWhite:BGSprite; - - var phillyLightsColors:Array; - var phillyWindow:BGSprite; - var phillyStreet:BGSprite; - var phillyTrain:BGSprite; - var blammedLightsBlack:FlxSprite; - var phillyWindowEvent:BGSprite; - var trainSound:FlxSound; - public var compactCombo:String; - public var compactScore:String; - public var compactMisses:String; - public var compactNPS:String; - public var compactMaxCombo:String; - public var compactTotalPlays:String; - - var phillyGlowGradient:PhillyGlow.PhillyGlowGradient; - var phillyGlowParticles:FlxTypedGroup; - - var limoKillingState:Int = 0; - var limo:BGSprite; - var limoMetalPole:BGSprite; - var limoLight:BGSprite; - var limoCorpse:BGSprite; - var limoCorpseTwo:BGSprite; - var bgLimo:BGSprite; - var grpLimoParticles:FlxTypedGroup; - var grpLimoDancers:FlxTypedGroup; - var fastCar:BGSprite; - - var upperBoppers:BGSprite; - var bottomBoppers:BGSprite; - var santa:BGSprite; - var heyTimer:Float; - - var bgGirls:BackgroundGirls; - var wiggleShit:WiggleEffect = new WiggleEffect(); - var bgGhouls:BGSprite; - var softlocked:Bool = false; - - var tankWatchtower:BGSprite; - var tankGround:BGSprite; - var tankmanRun:FlxTypedGroup; - var foregroundSprites:FlxTypedGroup; - - //ms timing popup shit - public var msTxt:FlxText; - public var msTimer:FlxTimer = null; - public var restartTimer:FlxTimer = null; - - public var maxScore:Int = 0; - public var oppScore:Float = 0; - public var songScore:Float = 0; - public var songHits:Int = 0; - public var songMisses:Int = 0; - public var scoreTxt:FlxText; - var comboTxt:FlxText; - var missTxt:FlxText; - var accuracyTxt:FlxText; - var npsTxt:FlxText; - var timeTxt:FlxText; - var timePercentTxt:FlxText; - - var hitTxt:FlxText; - - var scoreTxtTween:FlxTween; - var timeTxtTween:FlxTween; - var judgementCounter:FlxText; - - public static var campaignScore:Float = 0; - public static var campaignMisses:Int = 0; - public static var seenCutscene:Bool = false; - public static var deathCounter:Int = 0; - - public var defaultCamZoom:Float = 1.05; - - // how big to stretch the pixel art assets - public static var daPixelZoom:Float = 6; - public static var sectionsLoaded:Int = 0; - - public var inCutscene:Bool = false; - public var skipCountdown:Bool = false; - var songLength:Float = 0; - - public var boyfriendCameraOffset:Array = null; - public var opponentCameraOffset:Array = null; - public var girlfriendCameraOffset:Array = null; - - #if desktop - // Discord RPC variables - var storyDifficultyText:String = ""; - var detailsText:String = ""; - var detailsPausedText:String = ""; - #end - - //Achievement shit - var keysPressed:Array = []; - var boyfriendIdleTime:Float = 0.0; - var boyfriendIdled:Bool = false; - - // Lua shit - public var luaArray:Array = []; - public var achievementArray:Array = []; - public var achievementWeeks:Array = []; - private var luaDebugGroup:FlxTypedGroup; - public var introSoundsSuffix:String = ''; - - // Debug buttons - private var debugKeysChart:Array; - private var debugKeysCharacter:Array; - - // Less laggy controls - private var keysArray:Array; - private var controlArray:Array; - - var precacheList:Map = new Map(); - - // stores the last judgement object - public static var lastRating:FlxSprite; - // stores the last combo sprite object - public static var lastCombo:FlxSprite; - // stores the last combo score objects in an array - public static var lastScore:Array = []; - - //cam panning - var moveCamTo:HaxeVector = new HaxeVector(2); - - var getTheBotplayText:Int = 0; - - var theListBotplay:Array = []; - - override public function create() - { - var compactCombo:String = formatCompactNumber(combo); - var compactMaxCombo:String = formatCompactNumber(maxCombo); - var compactScore:String = formatCompactNumber(songScore); - var compactMisses:String = formatCompactNumberInt(songMisses); - var compactNPS:String = formatCompactNumber(nps); - var compactTotalPlays:String = formatCompactNumber(totalNotesPlayed); - theListBotplay = CoolUtil.coolTextFile(Paths.txt('botplayText')); - - randomBotplayText = theListBotplay[FlxG.random.int(0, theListBotplay.length - 1)]; - //trace('Playback Rate: ' + playbackRate); - - cpp.vm.Gc.enable(false); //lagspike prevention - - if (!ClientPrefs.memLeaks) - { - Paths.clearStoredMemory(); - - #if sys - openfl.system.System.gc(); - #end - } - - - // for lua - instance = this; - - - if (ClientPrefs.moreMaxHP) - { - maxHealth = 3; - } else - { - maxHealth = 2; - } - - debugKeysChart = ClientPrefs.copyKey(ClientPrefs.keyBinds.get('debug_1')); - debugKeysCharacter = ClientPrefs.copyKey(ClientPrefs.keyBinds.get('debug_2')); - PauseSubState.songName = null; //Reset to default - playbackRate = ClientPrefs.getGameplaySetting('songspeed', 1); - tauntKey = ClientPrefs.copyKey(ClientPrefs.keyBinds.get('qt_taunt')); - - keysArray = [ - ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_left')), - ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_down')), - ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_up')), - ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_right')) - ]; - - controlArray = [ - 'NOTE_LEFT', - 'NOTE_DOWN', - 'NOTE_UP', - 'NOTE_RIGHT' - ]; - - //Ratings - if (!ClientPrefs.noMarvJudge) - { - ratingsData.push(new Rating('marv')); - } - - var rating:Rating = new Rating('sick'); - rating.ratingMod = 1; - rating.score = 350; - rating.noteSplash = true; - ratingsData.push(rating); - - var rating:Rating = new Rating('good'); - rating.ratingMod = 0.7; - rating.score = 200; - rating.noteSplash = false; - ratingsData.push(rating); - - var rating:Rating = new Rating('bad'); - rating.ratingMod = 0.4; - rating.score = 100; - rating.noteSplash = false; - ratingsData.push(rating); - - var rating:Rating = new Rating('shit'); - rating.ratingMod = 0; - rating.score = 50; - rating.noteSplash = false; - ratingsData.push(rating); - - // For the "Just the Two of Us" achievement - for (i in 0...keysArray.length) - { - keysPressed.push(false); - } - - if (FlxG.sound.music != null) - FlxG.sound.music.stop(); - - // Gameplay settings - healthGain = ClientPrefs.getGameplaySetting('healthgain', 1); - healthLoss = ClientPrefs.getGameplaySetting('healthloss', 1); - hpDrainLevel = ClientPrefs.getGameplaySetting('drainlevel', 1); - instakillOnMiss = ClientPrefs.getGameplaySetting('instakill', false); - sickOnly = ClientPrefs.getGameplaySetting('onlySicks', false); - practiceMode = ClientPrefs.getGameplaySetting('practice', false); - cpuControlled = ClientPrefs.getGameplaySetting('botplay', false); - opponentChart = ClientPrefs.getGameplaySetting('opponentplay', false); - bothsides = ClientPrefs.getGameplaySetting('bothSides', false); - trollingMode = ClientPrefs.getGameplaySetting('thetrollingever', false); - opponentDrain = ClientPrefs.getGameplaySetting('opponentdrain', false); - randomMode = ClientPrefs.getGameplaySetting('randommode', false); - flip = ClientPrefs.getGameplaySetting('flip', false); - stairs = ClientPrefs.getGameplaySetting('stairmode', false); - waves = ClientPrefs.getGameplaySetting('wavemode', false); - oneK = ClientPrefs.getGameplaySetting('onekey', false); - randomSpeedThing = ClientPrefs.getGameplaySetting('randomspeed', false); - trollingMode = ClientPrefs.getGameplaySetting('thetrollingever', false); - jackingtime = ClientPrefs.getGameplaySetting('jacks', 0); - - if (trollingMode) - shouldKillNotes = false; - - if (ClientPrefs.showcaseMode) - cpuControlled = true; - - - // var gameCam:FlxCamera = FlxG.camera; - camGame = new FlxCamera(); - camHUD = new FlxCamera(); - camOther = new FlxCamera(); - camHUD.bgColor.alpha = 0; - camOther.bgColor.alpha = 0; - - FlxG.cameras.reset(camGame); - FlxG.cameras.add(camHUD, false); - FlxG.cameras.add(camOther, false); - grpNoteSplashes = new FlxTypedGroup((ClientPrefs.maxSplashLimit != 0 ? ClientPrefs.maxSplashLimit : 10000)); - - FlxG.cameras.setDefaultDrawTarget(camGame, true); - CustomFadeTransition.nextCamera = camOther; - - persistentUpdate = true; - persistentDraw = true; - if (SONG == null) - SONG = Song.loadFromJson('tutorial'); - - Conductor.mapBPMChanges(SONG); - Conductor.changeBPM(SONG.bpm); - - #if desktop - storyDifficultyText = CoolUtil.difficulties[storyDifficulty]; - - // String that contains the mode defined here so it isn't necessary to call changePresence for each mode - if (isStoryMode) - { - detailsText = "Story Mode: " + WeekData.getCurrentWeek().weekName; - } - else - { - detailsText = "Freeplay"; - } - - // String for when the game is paused - detailsPausedText = "BRB! - " + detailsText; - #end - - GameOverSubstate.resetVariables(); - var songName:String = Paths.formatToSongPath(SONG.song); - curStage = (!ClientPrefs.charsAndBG ? "" : SONG.stage); - //trace('stage is: ' + curStage); - if(SONG.stage == null || SONG.stage.length < 1) { - switch (songName) - { - case 'spookeez' | 'south' | 'monster': - curStage = 'spooky'; - case 'pico' | 'blammed' | 'philly' | 'philly-nice': - curStage = 'philly'; - case 'milf' | 'satin-panties' | 'high': - curStage = 'limo'; - case 'cocoa' | 'eggnog': - curStage = 'mall'; - case 'winter-horrorland': - curStage = 'mallEvil'; - case 'senpai' | 'roses': - curStage = 'school'; - case 'thorns': - curStage = 'schoolEvil'; - case 'ugh' | 'guns' | 'stress': - curStage = 'tank'; - default: - curStage = 'stage'; - } - } - SONG.stage = curStage; - - var stageData:StageFile = StageData.getStageFile(curStage); - if(stageData == null) { //Stage couldn't be found, create a dummy stage for preventing a crash - stageData = { - directory: "", - defaultZoom: 0.9, - isPixelStage: false, - - boyfriend: [770, 100], - girlfriend: [400, 130], - opponent: [100, 100], - hide_girlfriend: false, - - camera_boyfriend: [0, 0], - camera_opponent: [0, 0], - camera_girlfriend: [0, 0], - camera_speed: 1 - }; - } - - defaultCamZoom = stageData.defaultZoom; - isPixelStage = stageData.isPixelStage; - BF_X = stageData.boyfriend[0]; - BF_Y = stageData.boyfriend[1]; - GF_X = stageData.girlfriend[0]; - GF_Y = stageData.girlfriend[1]; - DAD_X = stageData.opponent[0]; - DAD_Y = stageData.opponent[1]; - - if(stageData.camera_speed != null) - cameraSpeed = stageData.camera_speed; - - boyfriendCameraOffset = stageData.camera_boyfriend; - if(boyfriendCameraOffset == null) //Fucks sake should have done it since the start :rolling_eyes: - boyfriendCameraOffset = [0, 0]; - - opponentCameraOffset = stageData.camera_opponent; - if(opponentCameraOffset == null) - opponentCameraOffset = [0, 0]; - - girlfriendCameraOffset = stageData.camera_girlfriend; - if(girlfriendCameraOffset == null) - girlfriendCameraOffset = [0, 0]; - - boyfriendGroup = new FlxSpriteGroup(BF_X, BF_Y); - dadGroup = new FlxSpriteGroup(DAD_X, DAD_Y); - gfGroup = new FlxSpriteGroup(GF_X, GF_Y); - - switch (curStage) - { - case 'stage': //Week 1 - var bg:BGSprite = new BGSprite('stageback', -600, -200, 0.9, 0.9); - add(bg); - - var stageFront:BGSprite = new BGSprite('stagefront', -650, 600, 0.9, 0.9); - stageFront.setGraphicSize(Std.int(stageFront.width * 1.1)); - stageFront.updateHitbox(); - add(stageFront); - if(!ClientPrefs.lowQuality) { - var stageLight:BGSprite = new BGSprite('stage_light', -125, -100, 0.9, 0.9); - stageLight.setGraphicSize(Std.int(stageLight.width * 1.1)); - stageLight.updateHitbox(); - add(stageLight); - var stageLight:BGSprite = new BGSprite('stage_light', 1225, -100, 0.9, 0.9); - stageLight.setGraphicSize(Std.int(stageLight.width * 1.1)); - stageLight.updateHitbox(); - stageLight.flipX = true; - add(stageLight); - - var stageCurtains:BGSprite = new BGSprite('stagecurtains', -500, -300, 1.3, 1.3); - stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9)); - stageCurtains.updateHitbox(); - add(stageCurtains); - } - dadbattleSmokes = new FlxSpriteGroup(); //troll'd - - case 'spooky': //Week 2 - if(!ClientPrefs.lowQuality) { - halloweenBG = new BGSprite('halloween_bg', -200, -100, ['halloweem bg0', 'halloweem bg lightning strike']); - } else { - halloweenBG = new BGSprite('halloween_bg_low', -200, -100); - } - add(halloweenBG); - - halloweenWhite = new BGSprite(null, -800, -400, 0, 0); - halloweenWhite.makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.WHITE); - halloweenWhite.alpha = 0; - halloweenWhite.blend = ADD; - - //PRECACHE SOUNDS - precacheList.set('thunder_1', 'sound'); - precacheList.set('thunder_2', 'sound'); - - case 'philly': //Week 3 - if(!ClientPrefs.lowQuality) { - var bg:BGSprite = new BGSprite('philly/sky', -100, 0, 0.1, 0.1); - add(bg); - } - - var city:BGSprite = new BGSprite('philly/city', -10, 0, 0.3, 0.3); - city.setGraphicSize(Std.int(city.width * 0.85)); - city.updateHitbox(); - add(city); - - phillyLightsColors = [0xFF31A2FD, 0xFF31FD8C, 0xFFFB33F5, 0xFFFD4531, 0xFFFBA633]; - phillyWindow = new BGSprite('philly/window', city.x, city.y, 0.3, 0.3); - phillyWindow.setGraphicSize(Std.int(phillyWindow.width * 0.85)); - phillyWindow.updateHitbox(); - add(phillyWindow); - phillyWindow.alpha = 0; - - if(!ClientPrefs.lowQuality) { - var streetBehind:BGSprite = new BGSprite('philly/behindTrain', -40, 50); - add(streetBehind); - } - - phillyTrain = new BGSprite('philly/train', 2000, 360); - add(phillyTrain); - - trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes')); - FlxG.sound.list.add(trainSound); - - phillyStreet = new BGSprite('philly/street', -40, 50); - add(phillyStreet); - - case 'limo': //Week 4 - var skyBG:BGSprite = new BGSprite('limo/limoSunset', -120, -50, 0.1, 0.1); - add(skyBG); - - if(!ClientPrefs.lowQuality) { - limoMetalPole = new BGSprite('gore/metalPole', -500, 220, 0.4, 0.4); - add(limoMetalPole); - - bgLimo = new BGSprite('limo/bgLimo', -150, 480, 0.4, 0.4, ['background limo pink'], true); - add(bgLimo); - - limoCorpse = new BGSprite('gore/noooooo', -500, limoMetalPole.y - 130, 0.4, 0.4, ['Henchmen on rail'], true); - add(limoCorpse); - - limoCorpseTwo = new BGSprite('gore/noooooo', -500, limoMetalPole.y, 0.4, 0.4, ['henchmen death'], true); - add(limoCorpseTwo); - - grpLimoDancers = new FlxTypedGroup(); - add(grpLimoDancers); - - for (i in 0...5) - { - var dancer:BackgroundDancer = new BackgroundDancer((370 * i) + 170, bgLimo.y - 400); - dancer.scrollFactor.set(0.4, 0.4); - grpLimoDancers.add(dancer); - } - - limoLight = new BGSprite('gore/coldHeartKiller', limoMetalPole.x - 180, limoMetalPole.y - 80, 0.4, 0.4); - add(limoLight); - - grpLimoParticles = new FlxTypedGroup(); - add(grpLimoParticles); - - //PRECACHE BLOOD - var particle:BGSprite = new BGSprite('gore/stupidBlood', -400, -400, 0.4, 0.4, ['blood'], false); - particle.alpha = 0.01; - grpLimoParticles.add(particle); - resetLimoKill(); - - //PRECACHE SOUND - precacheList.set('dancerdeath', 'sound'); - } - - limo = new BGSprite('limo/limoDrive', -120, 550, 1, 1, ['Limo stage'], true); - - fastCar = new BGSprite('limo/fastCarLol', -300, 160); - fastCar.active = true; - limoKillingState = 0; - - case 'mall': //Week 5 - Cocoa, Eggnog - var bg:BGSprite = new BGSprite('christmas/bgWalls', -1000, -500, 0.2, 0.2); - bg.setGraphicSize(Std.int(bg.width * 0.8)); - bg.updateHitbox(); - add(bg); - - if(!ClientPrefs.lowQuality) { - upperBoppers = new BGSprite('christmas/upperBop', -240, -90, 0.33, 0.33, ['Upper Crowd Bob']); - upperBoppers.setGraphicSize(Std.int(upperBoppers.width * 0.85)); - upperBoppers.updateHitbox(); - add(upperBoppers); - - var bgEscalator:BGSprite = new BGSprite('christmas/bgEscalator', -1100, -600, 0.3, 0.3); - bgEscalator.setGraphicSize(Std.int(bgEscalator.width * 0.9)); - bgEscalator.updateHitbox(); - add(bgEscalator); - } - - var tree:BGSprite = new BGSprite('christmas/christmasTree', 370, -250, 0.40, 0.40); - add(tree); - - bottomBoppers = new BGSprite('christmas/bottomBop', -300, 140, 0.9, 0.9, ['Bottom Level Boppers Idle']); - bottomBoppers.animation.addByPrefix('hey', 'Bottom Level Boppers HEY', 24, false); - bottomBoppers.setGraphicSize(Std.int(bottomBoppers.width * 1)); - bottomBoppers.updateHitbox(); - add(bottomBoppers); - - var fgSnow:BGSprite = new BGSprite('christmas/fgSnow', -600, 700); - add(fgSnow); - - santa = new BGSprite('christmas/santa', -840, 150, 1, 1, ['santa idle in fear']); - add(santa); - precacheList.set('Lights_Shut_off', 'sound'); - - case 'mallEvil': //Week 5 - Winter Horrorland - var bg:BGSprite = new BGSprite('christmas/evilBG', -400, -500, 0.2, 0.2); - bg.setGraphicSize(Std.int(bg.width * 0.8)); - bg.updateHitbox(); - add(bg); - - var evilTree:BGSprite = new BGSprite('christmas/evilTree', 300, -300, 0.2, 0.2); - add(evilTree); - - var evilSnow:BGSprite = new BGSprite('christmas/evilSnow', -200, 700); - add(evilSnow); - - case 'school': //Week 6 - Senpai, Roses - GameOverSubstate.deathSoundName = 'fnf_loss_sfx-pixel'; - GameOverSubstate.loopSoundName = 'gameOver-pixel'; - GameOverSubstate.endSoundName = 'gameOverEnd-pixel'; - GameOverSubstate.characterName = 'bf-pixel-dead'; - - var bgSky:BGSprite = new BGSprite('weeb/weebSky', 0, 0, 0.1, 0.1); - add(bgSky); - bgSky.antialiasing = false; - - var repositionShit = -200; - - var bgSchool:BGSprite = new BGSprite('weeb/weebSchool', repositionShit, 0, 0.6, 0.90); - add(bgSchool); - bgSchool.antialiasing = false; - - var bgStreet:BGSprite = new BGSprite('weeb/weebStreet', repositionShit, 0, 0.95, 0.95); - add(bgStreet); - bgStreet.antialiasing = false; - - var widShit = Std.int(bgSky.width * 6); - if(!ClientPrefs.lowQuality) { - var fgTrees:BGSprite = new BGSprite('weeb/weebTreesBack', repositionShit + 170, 130, 0.9, 0.9); - fgTrees.setGraphicSize(Std.int(widShit * 0.8)); - fgTrees.updateHitbox(); - add(fgTrees); - fgTrees.antialiasing = false; - } - - var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800); - bgTrees.frames = Paths.getPackerAtlas('weeb/weebTrees'); - 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); - bgTrees.antialiasing = false; - - if(!ClientPrefs.lowQuality) { - var treeLeaves:BGSprite = new BGSprite('weeb/petals', repositionShit, -40, 0.85, 0.85, ['PETALS ALL'], true); - treeLeaves.setGraphicSize(widShit); - treeLeaves.updateHitbox(); - add(treeLeaves); - treeLeaves.antialiasing = false; - } - - bgSky.setGraphicSize(widShit); - bgSchool.setGraphicSize(widShit); - bgStreet.setGraphicSize(widShit); - bgTrees.setGraphicSize(Std.int(widShit * 1.4)); - - bgSky.updateHitbox(); - bgSchool.updateHitbox(); - bgStreet.updateHitbox(); - bgTrees.updateHitbox(); - - if(!ClientPrefs.lowQuality) { - bgGirls = new BackgroundGirls(-100, 190); - bgGirls.scrollFactor.set(0.9, 0.9); - - bgGirls.setGraphicSize(Std.int(bgGirls.width * daPixelZoom)); - bgGirls.updateHitbox(); - add(bgGirls); - } - - case 'schoolEvil': //Week 6 - Thorns - GameOverSubstate.deathSoundName = 'fnf_loss_sfx-pixel'; - GameOverSubstate.loopSoundName = 'gameOver-pixel'; - GameOverSubstate.endSoundName = 'gameOverEnd-pixel'; - GameOverSubstate.characterName = 'bf-pixel-dead'; - - /*if(!ClientPrefs.lowQuality) { //Does this even do something? - 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; - if(!ClientPrefs.lowQuality) { - var bg:BGSprite = new BGSprite('weeb/animatedEvilSchool', posX, posY, 0.8, 0.9, ['background 2'], true); - bg.scale.set(6, 6); - bg.antialiasing = false; - add(bg); - - bgGhouls = new BGSprite('weeb/bgGhouls', -100, 190, 0.9, 0.9, ['BG freaks glitch instance'], false); - bgGhouls.setGraphicSize(Std.int(bgGhouls.width * daPixelZoom)); - bgGhouls.updateHitbox(); - bgGhouls.visible = false; - bgGhouls.antialiasing = false; - add(bgGhouls); - } else { - var bg:BGSprite = new BGSprite('weeb/animatedEvilSchool_low', posX, posY, 0.8, 0.9); - bg.scale.set(6, 6); - bg.antialiasing = false; - add(bg); - } - - case 'tank': //Week 7 - Ugh, Guns, Stress - var sky:BGSprite = new BGSprite('tankSky', -400, -400, 0, 0); - add(sky); - - if(!ClientPrefs.lowQuality) - { - var clouds:BGSprite = new BGSprite('tankClouds', FlxG.random.int(-700, -100), FlxG.random.int(-20, 20), 0.1, 0.1); - clouds.active = true; - clouds.velocity.x = FlxG.random.float(5, 15); - add(clouds); - - var mountains:BGSprite = new BGSprite('tankMountains', -300, -20, 0.2, 0.2); - mountains.setGraphicSize(Std.int(1.2 * mountains.width)); - mountains.updateHitbox(); - add(mountains); - - var buildings:BGSprite = new BGSprite('tankBuildings', -200, 0, 0.3, 0.3); - buildings.setGraphicSize(Std.int(1.1 * buildings.width)); - buildings.updateHitbox(); - add(buildings); - } - - var ruins:BGSprite = new BGSprite('tankRuins',-200,0,.35,.35); - ruins.setGraphicSize(Std.int(1.1 * ruins.width)); - ruins.updateHitbox(); - add(ruins); - - if(!ClientPrefs.lowQuality) - { - var smokeLeft:BGSprite = new BGSprite('smokeLeft', -200, -100, 0.4, 0.4, ['SmokeBlurLeft'], true); - add(smokeLeft); - var smokeRight:BGSprite = new BGSprite('smokeRight', 1100, -100, 0.4, 0.4, ['SmokeRight'], true); - add(smokeRight); - - tankWatchtower = new BGSprite('tankWatchtower', 100, 50, 0.5, 0.5, ['watchtower gradient color']); - add(tankWatchtower); - } - - tankGround = new BGSprite('tankRolling', 300, 300, 0.5, 0.5,['BG tank w lighting'], true); - add(tankGround); - - tankmanRun = new FlxTypedGroup(); - add(tankmanRun); - - var ground:BGSprite = new BGSprite('tankGround', -420, -150); - ground.setGraphicSize(Std.int(1.15 * ground.width)); - ground.updateHitbox(); - add(ground); - moveTank(); - - foregroundSprites = new FlxTypedGroup(); - foregroundSprites.add(new BGSprite('tank0', -500, 650, 1.7, 1.5, ['fg'])); - if(!ClientPrefs.lowQuality) foregroundSprites.add(new BGSprite('tank1', -300, 750, 2, 0.2, ['fg'])); - foregroundSprites.add(new BGSprite('tank2', 450, 940, 1.5, 1.5, ['foreground'])); - if(!ClientPrefs.lowQuality) foregroundSprites.add(new BGSprite('tank4', 1300, 900, 1.5, 1.5, ['fg'])); - foregroundSprites.add(new BGSprite('tank5', 1620, 700, 1.5, 1.5, ['fg'])); - if(!ClientPrefs.lowQuality) foregroundSprites.add(new BGSprite('tank3', 1300, 1200, 3.5, 2.5, ['fg'])); - } - - switch(Paths.formatToSongPath(SONG.song)) - { - case 'stress': - GameOverSubstate.characterName = 'bf-holding-gf-dead'; - } - - if(isPixelStage) { - introSoundsSuffix = '-pixel'; - } - - dadGhost = new FlxSprite(); - bfGhost = new FlxSprite(); - gfGhost = new FlxSprite(); - add(gfGroup); //Needed for blammed lights - if (ClientPrefs.doubleGhost) - { - add(bfGhost); - add(gfGhost); - add(dadGhost); - } - - // Shitty layering but whatev it works LOL - if (curStage == 'limo') - add(limo); - - add(dadGroup); - add(boyfriendGroup); - - switch(curStage) - { - case 'spooky': - add(halloweenWhite); - case 'tank': - add(foregroundSprites); - } - - #if LUA_ALLOWED - luaDebugGroup = new FlxTypedGroup(); - luaDebugGroup.cameras = [camOther]; - add(luaDebugGroup); - #end - - // "GLOBAL" SCRIPTS - #if LUA_ALLOWED - var filesPushed:Array = []; - var foldersToCheck:Array = [SUtil.getPath() + Paths.getPreloadPath('scripts/')]; - - #if MODS_ALLOWED - foldersToCheck.insert(0, Paths.mods('scripts/')); - if(Paths.currentModDirectory != null && Paths.currentModDirectory.length > 0) - foldersToCheck.insert(0, Paths.mods(Paths.currentModDirectory + '/scripts/')); - - for(mod in Paths.getGlobalMods()) - foldersToCheck.insert(0, Paths.mods(mod + '/scripts/')); - #end - - for (folder in foldersToCheck) - { - if(FileSystem.exists(folder)) - { - for (file in FileSystem.readDirectory(folder)) - { - if(file.endsWith('.lua') && !filesPushed.contains(file)) - { - luaArray.push(new FunkinLua(folder + file)); - filesPushed.push(file); - } - } - } - } - #end - - - //CUSTOM ACHIVEMENTS - #if (MODS_ALLOWED && LUA_ALLOWED && ACHIEVEMENTS_ALLOWED) - var luaFiles:Array = Achievements.getModAchievements().copy(); - if(luaFiles.length > 0){ - for(luaFile in luaFiles) - { - var lua = new FunkinLua(luaFile); - luaArray.push(lua); - achievementArray.push(lua); - } - } - - var achievementMetas = Achievements.getModAchievementMetas().copy(); - for (i in achievementMetas) { - if(i.lua_code != null) { - var lua = new FunkinLua(null, i.lua_code); - luaArray.push(lua); - achievementArray.push(lua); - } - if(i.week_nomiss != null) { - achievementWeeks.push(i.week_nomiss); - } - } - #end - - // STAGE SCRIPTS - #if (MODS_ALLOWED && LUA_ALLOWED) - startLuasOnFolder('stages/' + curStage + '.lua'); - #end - if(ClientPrefs.communityGameMode) - { - SONG.gfVersion = 'gf-bent'; - trace('using the suspicious gf skin, horny ass mf.'); - } - var gfVersion:String = SONG.gfVersion; - - if(gfVersion == null || gfVersion.length < 1) - { - switch (curStage) - { - case 'limo': - gfVersion = 'gf-car'; - case 'mall' | 'mallEvil': - gfVersion = 'gf-christmas'; - case 'school' | 'schoolEvil': - gfVersion = 'gf-pixel'; - case 'tank': - gfVersion = 'gf-tankmen'; - default: - gfVersion = 'gf'; - } - - - switch(Paths.formatToSongPath(SONG.song)) - { - case 'stress': - gfVersion = 'pico-speaker'; - } - SONG.gfVersion = gfVersion; //Fix for the Chart Editor - - } - health = maxHealth / 2; - displayedHealth = maxHealth / 2; - - if (!stageData.hide_girlfriend && ClientPrefs.charsAndBG) - { - gf = new Character(0, 0, gfVersion); - startCharacterPos(gf); - gf.scrollFactor.set(0.95, 0.95); - gfGroup.add(gf); - startCharacterLua(gf.curCharacter); - - if(gfVersion == 'pico-speaker') - { - if(!ClientPrefs.lowQuality) - { - var firstTank:TankmenBG = new TankmenBG(20, 500, true); - firstTank.resetShit(20, 600, true); - firstTank.strumTime = 10; - tankmanRun.add(firstTank); - - for (i in 0...TankmenBG.animationNotes.length) - { - if(FlxG.random.bool(16)) { - var tankBih = tankmanRun.recycle(TankmenBG); - tankBih.strumTime = TankmenBG.animationNotes[i][0]; - tankBih.resetShit(500, 200 + FlxG.random.int(50, 100), TankmenBG.animationNotes[i][1] < 2); - tankmanRun.add(tankBih); - } - } - } - } - } - - if (ClientPrefs.rateNameStuff == 'Quotes') - { - ratingStuff = [ - ['you suck ass lol', 0.2], //From 0% to 19% - ['you aint doin good', 0.4], //From 20% to 39% - ['Bad', 0.5], //From 40% to 49% - ['Bruh', 0.6], //From 50% to 59% - ['Meh', 0.69], //From 60% to 68% - ['funny number', 0.69417], //69.0% to 69.419% ( ͡° ͜ʖ ͡°) - ['( ͡° ͜ʖ ͡°)', 0.6943], //69.420% ( ͡° ͜ʖ ͡°) - ['funny number', 0.7], //69.421% to 69.999% ( ͡° ͜ʖ ͡°) - ['nice', 0.8], //From 70% to 79% - ['awesome', 0.9], //From 80% to 89% - ['thats amazing', 1], //From 90% to 99% - ['PERFECT!!!!!!', 1] //The value on this one isn't used actually, since Perfect is always "1" - ]; - } - if (ClientPrefs.rateNameStuff == 'Psych Quotes') - { - ratingStuff = [ - ['How are you this bad?', 0.1], //From 0% to 9% - ['You Suck!', 0.2], //From 10% to 19% - ['Horribly Shit', 0.3], //From 20% to 29% - ['Shit', 0.4], //From 30% to 39% - ['Bad', 0.5], //From 40% to 49% - ['Bruh', 0.6], //From 50% to 59% - ['Meh', 0.69], //From 60% to 68% - ['Nice', 0.7], //69% - ['Good', 0.8], //From 70% to 79% - ['Great', 0.9], //From 80% to 89% - ['Sick!', 1], //From 90% to 99% - ['Perfect!!', 1] //The value on this one isn't used actually, since Perfect is always "1" - ]; - } - if (ClientPrefs.rateNameStuff == 'Shaggyverse Quotes') - { - ratingStuff = [ - ['G - Ruh Rouh!', 0.2], //From 0% to 19% - ['F - OOF', 0.4], //From 20% to 39% - ["E - Like, You're Bad", 0.5], //From 40% to 49% - ['D - Like, how are you still alive?', 0.6], //From 50% to 59% - ['C - ZOINKS!', 0.69], //From 60% to 68% - ["Nice - WOW, that's a funny number man!", 0.7], //69% - ["B - That's like, really cool...", 0.75], //From 70% to 74% - ["B+ - Hey, man, you're starting to improve!", 0.8], //From 75% to 79% - ['A - This is a challenge!', 0.85], //From 80% to 84% - ['AA - Hey Scoob, This kid is good!', 0.9], //From 85% to 90% - ['S - Like, Thats Good', 0.95], //From 90% to 94% - ['SS - Like, Thats Great!', 0.99], //From 95% to 98% - ['SSS - Like, Thats Sick!', 1], //99% - ['SSSS - Like, WOW', 1] //The value on this one isn't used actually, since Perfect is always "1" - ]; - } - if (ClientPrefs.rateNameStuff == 'Letters') - { - ratingStuff = [ - ['HOW?', 0.2], //From 0% to 19% - ['F', 0.4], //From 20% to 39% - ['E', 0.5], //From 40% to 49% - ['D', 0.6], //From 50% to 59% - ['C', 0.69], //From 60% to 68% - ['FUNNY', 0.7], //69% - ['B', 0.8], //From 70% to 79% - ['A', 0.9], //From 80% to 89% - ['S', 0.97], //From 90% to 98% - ['S+', 1], //98% to 99% - ['X', 1] //The value on this one isn't used actually, since Perfect is always "1" - ]; - } - if (!ClientPrefs.charsAndBG) - { - dad = new Character(0, 0, ""); - dadGroup.add(dad); - - boyfriend = new Boyfriend(0, 0, ""); - boyfriendGroup.add(boyfriend); - } else - { - dad = new Character(0, 0, SONG.player2); - startCharacterPos(dad, true); - dadGroup.add(dad); - startCharacterLua(dad.curCharacter); - - boyfriend = new Boyfriend(0, 0, SONG.player1); - startCharacterPos(boyfriend); - boyfriendGroup.add(boyfriend); - startCharacterLua(boyfriend.curCharacter); - } - if (ClientPrefs.doubleGhost || ClientPrefs.charsAndBG) - { - dadGhost.visible = false; - dadGhost.antialiasing = true; - dadGhost.scale.copyFrom(dad.scale); - dadGhost.updateHitbox(); - bfGhost.visible = false; - bfGhost.antialiasing = true; - bfGhost.scale.copyFrom(boyfriend.scale); - bfGhost.updateHitbox(); - if (!stageData.hide_girlfriend || ClientPrefs.charsAndBG && !stageData.hide_girlfriend) { //stops crashes if the stage data specifies to hide gf - gfGhost.visible = false; - gfGhost.antialiasing = true; - gfGhost.scale.copyFrom(gf.scale); - gfGhost.updateHitbox(); - } - } - - var camPos:FlxPoint = new FlxPoint(girlfriendCameraOffset[0], girlfriendCameraOffset[1]); - if(gf != null) - { - camPos.x += gf.getGraphicMidpoint().x + gf.cameraPosition[0]; - camPos.y += gf.getGraphicMidpoint().y + gf.cameraPosition[1]; - } - - if(dad.curCharacter.startsWith('gf')) { - dad.setPosition(GF_X, GF_Y); - if(gf != null) - gf.visible = false; - } - - switch(curStage) - { - case 'limo': - resetFastCar(); - addBehindGF(fastCar); - - case 'schoolEvil': - var evilTrail = new FlxTrail(dad, null, 4, 24, 0.3, 0.069); //nice - addBehindDad(evilTrail); - } - - var file:String = Paths.json(songName + '/dialogue'); //Checks for json/Psych Engine dialogue - if (OpenFlAssets.exists(file)) { - dialogueJson = DialogueBoxPsych.parseDialogue(SUtil.getPath() + file); - } - - var file:String = Paths.txt(songName + '/' + songName + 'Dialogue'); //Checks for vanilla/Senpai dialogue - if (OpenFlAssets.exists(file)) { - dialogue = CoolUtil.coolTextFile(SUtil.getPath() + file); - } - var doof:DialogueBox = new DialogueBox(false, dialogue); - // doof.x += 70; - // doof.y = FlxG.height * 0.5; - doof.scrollFactor.set(); - doof.finishThing = startCountdown; - doof.nextDialogueThing = startNextDialogue; - doof.skipDialogueThing = skipDialogue; - - Conductor.songPosition = -5000 / Conductor.songPosition; - - laneunderlayOpponent = new FlxSprite(70, 0).makeGraphic(500, FlxG.height * 2, FlxColor.BLACK); - laneunderlayOpponent.alpha = ClientPrefs.laneUnderlayAlpha; - laneunderlayOpponent.scrollFactor.set(); - laneunderlayOpponent.screenCenter(Y); - laneunderlayOpponent.visible = ClientPrefs.laneUnderlay; - - laneunderlay = new FlxSprite(70 + (FlxG.width / 2), 0).makeGraphic(500, FlxG.height * 2, FlxColor.BLACK); - laneunderlay.alpha = ClientPrefs.laneUnderlayAlpha; - laneunderlay.scrollFactor.set(); - laneunderlay.screenCenter(Y); - laneunderlay.visible = ClientPrefs.laneUnderlay; - - if (ClientPrefs.laneUnderlay) - { - add(laneunderlayOpponent); - add(laneunderlay); - } - - strumLine = new FlxSprite(ClientPrefs.middleScroll ? STRUM_X_MIDDLESCROLL : STRUM_X, 50).makeGraphic(FlxG.width, 10); - if(ClientPrefs.downScroll) strumLine.y = FlxG.height - 150; - strumLine.scrollFactor.set(); - - var showTime:Bool = (ClientPrefs.timeBarType != 'Disabled'); - - if (ClientPrefs.hudType == 'Psych Engine') { - timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); - timeTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.scrollFactor.set(); - timeTxt.alpha = 0; - timeTxt.borderSize = 2; - timeTxt.visible = showTime; - if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; - } - if (ClientPrefs.hudType == 'Leather Engine') { - timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); - timeTxt.setFormat(Paths.font("vcr.ttf"), 18, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.scrollFactor.set(); - timeTxt.alpha = 0; - timeTxt.borderSize = 2; - timeTxt.visible = showTime; - if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; - } - if (ClientPrefs.hudType == 'JS Engine') { - timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 20); - timeTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.scrollFactor.set(); - timeTxt.alpha = 0; - timeTxt.borderSize = 3; - timeTxt.visible = showTime; - if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; - } - if (ClientPrefs.hudType == 'Tails Gets Trolled V4') { - timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); - timeTxt.setFormat(Paths.font("calibri.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.scrollFactor.set(); - timeTxt.alpha = 0; - timeTxt.borderSize = 2; - timeTxt.visible = showTime; - if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; - } - if (ClientPrefs.hudType == 'Kade Engine') { - timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 18); - timeTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.scrollFactor.set(); - timeTxt.alpha = 0; - timeTxt.borderSize = 1; - timeTxt.visible = showTime; - if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; - } - if (ClientPrefs.hudType == 'Dave and Bambi') { - timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); - timeTxt.setFormat(Paths.font("comic.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.scrollFactor.set(); - timeTxt.alpha = 0; - timeTxt.borderSize = 2; - timeTxt.visible = showTime; - if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; - } - if (ClientPrefs.hudType == 'Doki Doki+') { - timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); - timeTxt.setFormat(Paths.font("Aller_rg.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.scrollFactor.set(); - timeTxt.alpha = 0; - timeTxt.borderSize = 2; - timeTxt.visible = showTime; - if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; - } - if (ClientPrefs.hudType == 'VS Impostor') { - timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 585, 20, 400, "", 32); - timeTxt.setFormat(Paths.font("vcr.ttf"), 14, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.scrollFactor.set(); - timeTxt.alpha = 0; - timeTxt.borderSize = 1; - timeTxt.visible = showTime; - if (ClientPrefs.downScroll) timeTxt.y = FlxG.height - 45; - } - if (ClientPrefs.hudType == "Mic'd Up") { - timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 16); - if (ClientPrefs.downScroll) - timeTxt.y = FlxG.height - 44; - timeTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.scrollFactor.set(); - timeTxt.screenCenter(X); - timeTxt.visible = showTime; - } - - - if(ClientPrefs.timeBarType == 'Song Name' && !ClientPrefs.timebarShowSpeed) - { - timeTxt.text = SONG.song; - } - updateTime = showTime; - - if (ClientPrefs.hudType == 'VS Impostor') { - timeBarBG = new AttachedSprite('impostorTimeBar'); - timeBarBG.x = timeTxt.x; - timeBarBG.y = timeTxt.y + (timeTxt.height / 4); - timeBarBG.scrollFactor.set(); - timeBarBG.alpha = 0; - timeBarBG.visible = showTime; - // timeBarBG.color = FlxColor.BLACK; - timeBarBG.antialiasing = false; - timeBarBG.xAdd = -4; - timeBarBG.yAdd = -4; - add(timeBarBG); - - - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, - 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.createFilledBar(0xFF2e412e, 0xFF44d844); - timeBar.numDivisions = 800; // How much lag this causes?? Should i tone it down to idk, 400 or 200? - timeBar.alpha = 0; - timeBar.visible = showTime; - add(timeBar); - add(timeTxt); - timeBarBG.sprTracker = timeBar; - timeTxt.x += 10; - timeTxt.y += 4; - } - - if (ClientPrefs.hudType == 'Psych Engine') { - timeBarBG = new AttachedSprite('timeBar'); - timeBarBG.x = timeTxt.x; - timeBarBG.y = timeTxt.y + (timeTxt.height / 4); - timeBarBG.scrollFactor.set(); - timeBarBG.alpha = 0; - timeBarBG.visible = showTime; - timeBarBG.color = FlxColor.BLACK; - timeBarBG.xAdd = -4; - timeBarBG.yAdd = -4; - add(timeBarBG); - - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, - 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.createFilledBar(0xFF000000, 0xFFFFFFFF); - timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? - timeBar.alpha = 0; - timeBar.visible = showTime; - add(timeBar); - add(timeTxt); - timeBarBG.sprTracker = timeBar; - } - if (ClientPrefs.hudType == 'Leather Engine') { - timeBarBG = new AttachedSprite('healthBar'); - timeBarBG.x = timeTxt.x; - timeBarBG.y = timeTxt.y + (timeTxt.height / 8); - timeBarBG.scrollFactor.set(); - timeBarBG.alpha = 0; - timeBarBG.visible = showTime; - timeBarBG.color = FlxColor.BLACK; - timeBarBG.xAdd = -4; - timeBarBG.yAdd = -4; - timeBarBG.screenCenter(X); - add(timeBarBG); - - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, - 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.createFilledBar(FlxColor.BLACK, FlxColor.WHITE); - timeBar.numDivisions = 400; - timeBar.alpha = 0; - timeBar.visible = showTime; - add(timeBar); - add(timeTxt); - } - if (ClientPrefs.hudType == 'Tails Gets Trolled V4') { - timeBarBG = new AttachedSprite('timeBar'); - timeBarBG.x = timeTxt.x; - timeBarBG.y = timeTxt.y + (timeTxt.height / 4); - timeBarBG.scrollFactor.set(); - timeBarBG.alpha = 0; - timeBarBG.visible = showTime; - timeBarBG.color = FlxColor.BLACK; - timeBarBG.xAdd = -4; - timeBarBG.yAdd = -4; - add(timeBarBG); - - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, - 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.createFilledBar(0xFF000000, 0xFFFFFFFF); - timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? - timeBar.alpha = 0; - timeBar.visible = showTime; - add(timeBar); - add(timeTxt); - timeBarBG.sprTracker = timeBar; - } - if (ClientPrefs.hudType == 'Box Funkin') { - timeBarBG = new AttachedSprite('WITimeBar'); - timeBarBG.y = 695; - if (ClientPrefs.downScroll) timeBarBG.y = 3; - timeBarBG.scrollFactor.set(); - timeBarBG.updateHitbox(); - timeBarBG.screenCenter(X); - timeBarBG.alpha = 0; - add(timeBarBG); - timeBarBG.xAdd = -12; - timeBarBG.yAdd = -4; - timeBarBG.screenCenter(X); - timeBarBG.color = FlxColor.BLACK; - - timeTxt = new FlxText(0, (ClientPrefs.downScroll ? timeBarBG.y + 32 : timeBarBG.y - 32), 400, "", 20); - timeTxt.setFormat(Paths.font("MilkyNice.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timeTxt.alpha = 0; - timeTxt.borderSize = 3; - timeTxt.screenCenter(X); - timeTxt.antialiasing = ClientPrefs.globalAntialiasing; - updateTime = true; - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 5, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 24), Std.int(timeBarBG.height - 8), this, 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.createFilledBar(0xFF000000, 0xFFFFFFFF); - timeBar.numDivisions = 800; // How much lag this causes?? Should i tone it down to idk, 400 or 200? - timeBar.alpha = 0; - timeBarBG.xAdd = -12; - timeBar.screenCenter(X); - add(timeBar); - add(timeTxt); - timeBarBG.sprTracker = timeBar; - } - - if (ClientPrefs.hudType == 'Kade Engine') { - timeBarBG = new AttachedSprite('healthBar'); - timeBarBG.x = timeTxt.x; - timeBarBG.y = timeTxt.y + (timeTxt.height / 8); - timeBarBG.scrollFactor.set(); - timeBarBG.alpha = 0; - timeBarBG.visible = showTime; - timeBarBG.color = FlxColor.BLACK; - timeBarBG.xAdd = -4; - timeBarBG.yAdd = -4; - timeBarBG.screenCenter(X); - add(timeBarBG); - - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, - 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); - timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? - timeBar.alpha = 0; - timeBar.visible = showTime; - add(timeBar); - add(timeTxt); - timeBarBG.sprTracker = timeBar; - } - - if (ClientPrefs.hudType == "Mic'd Up") { - timeBarBG = new AttachedSprite('healthBar'); - timeBarBG.x = timeTxt.x; - timeBarBG.y = timeTxt.y + (timeTxt.height / 8); - timeBarBG.scrollFactor.set(); - timeBarBG.alpha = 0; - timeBarBG.visible = showTime; - timeBarBG.color = FlxColor.BLACK; - timeBarBG.xAdd = -4; - timeBarBG.yAdd = -4; - timeBarBG.screenCenter(X); - add(timeBarBG); - - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, - 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); - timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? - timeBar.alpha = 0; - timeBar.visible = showTime; - add(timeBar); - timeBarBG.sprTracker = timeBar; - add(timeTxt); - } - - if (ClientPrefs.hudType == 'Dave and Bambi') { - timeBarBG = new AttachedSprite('DnBTimeBar'); - timeBarBG.screenCenter(X); - timeBarBG.y = timeTxt.y + (timeTxt.height / 4); - timeBarBG.antialiasing = true; - timeBarBG.scrollFactor.set(); - timeBarBG.visible = showTime; - timeBarBG.xAdd = -4; - timeBarBG.yAdd = -4; - add(timeBarBG); - - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, - 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? - timeBar.alpha = 0; - timeBar.visible = showTime; - add(timeTxt); - timeBarBG.sprTracker = timeBar; - timeBar.createFilledBar(FlxColor.GRAY, FlxColor.fromRGB(57, 255, 20)); - insert(members.indexOf(timeBarBG), timeBar); - } - if (ClientPrefs.hudType == 'Doki Doki+') { - timeBarBG = new AttachedSprite('dokiTimeBar'); - timeBarBG.screenCenter(X); - timeBarBG.y = timeTxt.y + (timeTxt.height / 4); - timeBarBG.antialiasing = true; - timeBarBG.scrollFactor.set(); - timeBarBG.visible = showTime; - timeBarBG.xAdd = -4; - timeBarBG.yAdd = -4; - add(timeBarBG); - - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, - 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? - timeBar.alpha = 0; - timeBar.visible = showTime; - timeBarBG.sprTracker = timeBar; - timeBar.createGradientBar([FlxColor.TRANSPARENT], [FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2])]); - add(timeBar); - add(timeTxt); - } - if (ClientPrefs.hudType == 'JS Engine') { - timeBarBG = new AttachedSprite('healthBar'); - timeBarBG.screenCenter(X); - timeBarBG.x = timeTxt.x; - timeBarBG.y = timeTxt.y + (timeTxt.height / 8); - timeBarBG.scrollFactor.set(); - timeBarBG.alpha = 0; - timeBarBG.visible = showTime; - timeBarBG.color = FlxColor.BLACK; - timeBarBG.xAdd = -4; - timeBarBG.yAdd = -4; - timeBarBG.screenCenter(X); - add(timeBarBG); - - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, - 'songPercent', 0, 1); - timeBar.scrollFactor.set(); - timeBar.numDivisions = 1000; //How much lag this causes?? Should i tone it down to idk, 400 or 200? - timeBar.alpha = 0; - timeBar.visible = showTime; - timeBarBG.sprTracker = timeBar; - timeBar.createGradientBar([FlxColor.TRANSPARENT], [FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2]), FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])]); - add(timeBar); - add(timeTxt); - } - timePercentTxt = new FlxText(800, 19, 400, "", 32); - if (ClientPrefs.hudType == 'Doki Doki+') timePercentTxt.setFormat(Paths.font("Aller_rg.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - if (ClientPrefs.hudType == 'Tails Gets Trolled V4') timePercentTxt.setFormat(Paths.font("calibri.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - if (ClientPrefs.hudType == 'Dave and Bambi') timePercentTxt.setFormat(Paths.font("comic.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - if (ClientPrefs.hudType != 'Dave and Bambi' && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') timePercentTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - timePercentTxt.scrollFactor.set(); - timePercentTxt.alpha = 0; - timePercentTxt.borderSize = 2; - timePercentTxt.visible = ClientPrefs.songPercentage; - updateThePercent = ClientPrefs.songPercentage; - if(ClientPrefs.downScroll) timePercentTxt.y = FlxG.height - 44; - if (ClientPrefs.timeBarType == 'Disabled') timePercentTxt.screenCenter(X); - if (ClientPrefs.hudType == 'Kade Engine' && ClientPrefs.hudType == 'Dave and Bambi') timePercentTxt.x = timeBarBG.x + 600; - add(timePercentTxt); - - strumLineNotes = new FlxTypedGroup(); - add(strumLineNotes); - add(grpNoteSplashes); - - - if(ClientPrefs.timeBarType == 'Song Name' && ClientPrefs.hudType == 'VS Impostor') - { - timeTxt.size = 14; - } - - var splash:NoteSplash = new NoteSplash(100, 100, 0); - grpNoteSplashes.add(splash); - splash.alpha = 0.0; - - playerStrums = new FlxTypedGroup(); - opponentStrums = new FlxTypedGroup(); - - // startCountdown(); - trace ('Loading chart...'); - generateSong(SONG.song); - - if (curSong.toLowerCase() == "guns") // added this to bring back the old 2021 fnf vibes, i wish the fnf fandom revives one day :( - { - var randomVar:Int = 0; - if (!ClientPrefs.noGunsRNG) randomVar = Std.random(15); - if (ClientPrefs.noGunsRNG) randomVar = 8; - trace(randomVar); - if (randomVar == 8) - { - trace('AWW YEAH, ITS ASCENDING TIME'); - tankmanAscend = true; - } - } - - // After all characters being loaded, it makes then invisible 0.01s later so that the player won't freeze when you change characters - // add(strumLine); - - if (unspawnNotes[0] != null) firstNoteStrumTime = unspawnNotes[0].strumTime; - - camFollow = new FlxPoint(); - camFollowPos = new FlxObject(0, 0, 1, 1); - - snapCamFollowToPos(camPos.x, camPos.y); - if (prevCamFollow != null) - { - camFollow = prevCamFollow; - prevCamFollow = null; - } - if (prevCamFollowPos != null) - { - camFollowPos = prevCamFollowPos; - prevCamFollowPos = null; - } - add(camFollowPos); - if (!ClientPrefs.charsAndBG) FlxG.camera.zoom = 100; //zoom it in very big to avoid high RAM usage!! - if (ClientPrefs.charsAndBG) - { - FlxG.camera.follow(camFollowPos, LOCKON, 1); - // FlxG.camera.setScrollBounds(0, FlxG.width, 0, FlxG.height); - FlxG.camera.zoom = defaultCamZoom; - FlxG.camera.focusOn(camFollow); - - FlxG.worldBounds.set(0, 0, FlxG.width, FlxG.height); - } - FlxG.fixedTimestep = false; - moveCameraSection(); - - //omg its that ms text from earlier - msTxt = new FlxText(0, 0, 0, ""); - msTxt.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); - msTxt.scrollFactor.set(); - msTxt.setFormat("vcr.ttf", 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - if (ClientPrefs.hudType == 'Tails Gets Trolled V4') msTxt.setFormat("calibri.ttf", 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - if (ClientPrefs.hudType == 'Dave and Bambi') msTxt.setFormat("comic.ttf", 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - if (ClientPrefs.hudType == 'Doki Doki+') msTxt.setFormat("Aller_rg.ttf", 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - msTxt.x = 408 + 250; - msTxt.y = 290 - 25; - if (PlayState.isPixelStage) { - msTxt.x = 408 + 260; - msTxt.y = 290 + 20; - } - msTxt.x += ClientPrefs.comboOffset[0]; - msTxt.y -= ClientPrefs.comboOffset[1]; - msTxt.active = false; - msTxt.visible = false; - insert(members.indexOf(strumLineNotes), msTxt); - if (ClientPrefs.hudType == 'Dave and Bambi') - { - if (ClientPrefs.longHPBar) - { - healthBarBG = new AttachedSprite('longDnBHealthBar'); - } else - { - healthBarBG = new AttachedSprite('DnBHealthBar'); - } - healthBarBG.y = FlxG.height * 0.89; - if(ClientPrefs.downScroll) healthBarBG.y = 0.11 * FlxG.height; - healthBarBG.screenCenter(X); - healthBarBG.scrollFactor.set(); - healthBarBG.xAdd = -4; - healthBarBG.yAdd = -4; - healthBarBG.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - add(healthBarBG); - - healthBar = new FlxBar(healthBarBG.x + 4, healthBarBG.y + 4, (opponentChart ? LEFT_TO_RIGHT : RIGHT_TO_LEFT), Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, - 'displayedHealth', 0, maxHealth); - healthBar.scrollFactor.set(); - // healthBar - healthBar.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - healthBar.alpha = ClientPrefs.healthBarAlpha; - healthBarBG.sprTracker = healthBar; - insert(members.indexOf(healthBarBG), healthBar); - } - if (ClientPrefs.hudType == 'Doki Doki+') - { - if (ClientPrefs.longHPBar) - { - healthBarBG = new AttachedSprite('longDokiHealthBar'); - } else - { - healthBarBG = new AttachedSprite('dokiHealthBar'); - } - healthBarBG.y = FlxG.height * 0.89; - healthBarBG.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - if(ClientPrefs.downScroll) healthBarBG.y = 0.11 * FlxG.height; - healthBarBG.screenCenter(X); - healthBarBG.scrollFactor.set(); - healthBarBG.xAdd = -4; - healthBarBG.yAdd = -4; - add(healthBarBG); - - healthBar = new FlxBar(healthBarBG.x + 4, healthBarBG.y + 4, (opponentChart ? LEFT_TO_RIGHT : RIGHT_TO_LEFT), Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, - 'displayedHealth', 0, maxHealth); - healthBar.scrollFactor.set(); - // healthBar - healthBar.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - healthBar.alpha = ClientPrefs.healthBarAlpha; - healthBarBG.sprTracker = healthBar; - add(healthBar); - } else if (ClientPrefs.hudType != 'Dave and Bambi' && ClientPrefs.hudType != 'Doki Doki+') { - if (ClientPrefs.longHPBar) - { - healthBarBG = new AttachedSprite('longHealthBar'); - } else - { - healthBarBG = new AttachedSprite('healthBar'); - } - healthBarBG.y = FlxG.height * 0.89; - healthBarBG.screenCenter(X); - healthBarBG.scrollFactor.set(); - healthBarBG.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - healthBarBG.xAdd = -4; - healthBarBG.yAdd = -4; - add(healthBarBG); - if(ClientPrefs.downScroll) healthBarBG.y = 0.11 * FlxG.height; - - healthBar = new FlxBar(healthBarBG.x + 4, healthBarBG.y + 4, (opponentChart ? LEFT_TO_RIGHT : RIGHT_TO_LEFT), Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, - 'displayedHealth', 0, maxHealth); - healthBar.scrollFactor.set(); - // healthBar - healthBar.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - healthBar.alpha = ClientPrefs.healthBarAlpha; - add(healthBar); - healthBarBG.sprTracker = healthBar; - } - - iconP1 = new HealthIcon(boyfriend.healthIcon, true); - iconP1.y = healthBar.y - 75; - iconP1.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - iconP1.alpha = ClientPrefs.healthBarAlpha; - add(iconP1); - - iconP2 = new HealthIcon(dad.healthIcon, false); - iconP2.y = healthBar.y - 75; - iconP2.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - iconP2.alpha = ClientPrefs.healthBarAlpha; - add(iconP2); - reloadHealthBarColors(); - - if (ClientPrefs.bfIconStyle == 'VS Nonsense V2') iconP1.changeIcon('bfnonsense'); - if (ClientPrefs.bfIconStyle == 'Doki Doki+') iconP1.changeIcon('bfdoki'); - if (ClientPrefs.bfIconStyle == 'Leather Engine') iconP1.changeIcon('bfleather'); - - if (ClientPrefs.timeBarType == 'Disabled') { - timeBarBG.destroy(); - timeBar.destroy(); - } - - if (ClientPrefs.hudType == 'Kade Engine') { - // Add Engine watermark - EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); - EngineWatermark.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - EngineWatermark.scrollFactor.set(); - add(EngineWatermark); - EngineWatermark.text = SONG.song + " " + CoolUtil.difficultyString() + " | JSE " + MainMenuState.psychEngineJSVersion; - } - if (ClientPrefs.hudType == 'JS Engine') { - // Add Engine watermark - EngineWatermark = new FlxText(4,FlxG.height * 0.1 - 70,0,"", 15); - EngineWatermark.setFormat(Paths.font("vcr.ttf"), 18, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - EngineWatermark.scrollFactor.set(); - if (ClientPrefs.downScroll) EngineWatermark.y = (FlxG.height * 0.9 + 50); - add(EngineWatermark); - EngineWatermark.text = "You are now playing " + SONG.song + " on " + CoolUtil.difficultyString() + "! (JSE v" + MainMenuState.psychEngineJSVersion + ")"; - } - if (ClientPrefs.hudType == 'Dave and Bambi') { - // Add Engine watermark - EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); - EngineWatermark.setFormat(Paths.font("comic.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - EngineWatermark.scrollFactor.set(); - add(EngineWatermark); - EngineWatermark.text = SONG.song; - } - if (ClientPrefs.hudType == 'Doki Doki+') { - // Add Engine watermark - EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); - add(EngineWatermark); - } - if (ClientPrefs.hudType == 'Leather Engine') { - // Add Engine watermark BECAUSE THE ENGINE THING IS dumb - EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); - add(EngineWatermark); - } - if (ClientPrefs.hudType == 'VS Impostor') { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference - // Add Engine watermark - EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); - add(EngineWatermark); - } - if (ClientPrefs.hudType == 'Psych Engine') { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference - // Add Engine watermark - EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); - add(EngineWatermark); - } - if (ClientPrefs.hudType == 'Tails Gets Trolled V4') { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference - // Add Engine watermark - EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); - add(EngineWatermark); - } - if (ClientPrefs.hudType == "Mic'd Up") { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference - // Add Engine watermark - EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); - add(EngineWatermark); - } - if (ClientPrefs.hudType == 'Box Funkin') { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference - // Add Engine watermark - EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); - add(EngineWatermark); - } - - if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) { - //hitTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 20, 10000, "", 42); - hitTxt = new FlxText(0, 20, 10000, "test", 42); - hitTxt.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - hitTxt.scrollFactor.set(); - hitTxt.borderSize = 2; - hitTxt.visible = true; - hitTxt.cameras = [camHUD]; - //hitTxt.alignment = FlxTextAlign.LEFT; // center the text - //hitTxt.screenCenter(X); - hitTxt.screenCenter(Y); - add(hitTxt); - var chromaScreen = new FlxSprite(-5000, -2000).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.GREEN); - chromaScreen.scrollFactor.set(0, 0); - chromaScreen.scale.set(3, 3); - chromaScreen.updateHitbox(); - add(chromaScreen); - } - - if (ClientPrefs.hudType == 'Kade Engine') - { - scoreTxt = new FlxText(0, healthBarBG.y + 50, FlxG.width, "", 20); - scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - scoreTxt.scrollFactor.set(); - scoreTxt.borderSize = 1; - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - add(scoreTxt); - } - if (ClientPrefs.hudType == 'JS Engine') - { - scoreTxt = new FlxText(0, healthBarBG.y + 50, FlxG.width, "", 20); - scoreTxt.setFormat(Paths.font("vcr.ttf"), 18, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - scoreTxt.scrollFactor.set(); - scoreTxt.borderSize = 2; - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - add(scoreTxt); - } - if (ClientPrefs.hudType == "Mic'd Up") - { - scoreTxt = new FlxText(healthBarBG.x - (healthBarBG.width / 2), healthBarBG.y - 26, 0, "", 20); - if (ClientPrefs.downScroll) - scoreTxt.y = healthBarBG.y + 18; - scoreTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, RIGHT); - scoreTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - scoreTxt.scrollFactor.set(); - add(scoreTxt); - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - - missTxt = new FlxText(scoreTxt.x, scoreTxt.y - 26, 0, "", 20); - if (ClientPrefs.downScroll) - missTxt.y = scoreTxt.y + 26; - missTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, RIGHT); - missTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - missTxt.scrollFactor.set(); - add(missTxt); - missTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - - accuracyTxt = new FlxText(missTxt.x, missTxt.y - 26, 0, "", 20); - if (ClientPrefs.downScroll) - accuracyTxt.y = missTxt.y + 26; - accuracyTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, RIGHT); - accuracyTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - accuracyTxt.scrollFactor.set(); - add(accuracyTxt); - accuracyTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - - comboTxt = new FlxText(scoreTxt.x, scoreTxt.y + 26, 0, "", 21); - if (ClientPrefs.downScroll) - comboTxt.y = scoreTxt.y - 26; - comboTxt.setFormat(Paths.font("vcr.ttf"), 21, FlxColor.WHITE, RIGHT); - comboTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - comboTxt.scrollFactor.set(); - add(comboTxt); - comboTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - - npsTxt = new FlxText(accuracyTxt.x, accuracyTxt.y - 46, 0, "", 20); - if (ClientPrefs.downScroll) - npsTxt.y = accuracyTxt.y + 46; - npsTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, RIGHT); - npsTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - npsTxt.scrollFactor.set(); - add(npsTxt); - npsTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - } - if (ClientPrefs.hudType == 'Box Funkin') - { - scoreTxt = new FlxText(25, healthBarBG.y - 26, 0, "", 21); - if (ClientPrefs.downScroll) - scoreTxt.y = healthBarBG.y + 26; - scoreTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); - scoreTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - scoreTxt.scrollFactor.set(); - add(scoreTxt); - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - - missTxt = new FlxText(scoreTxt.x, scoreTxt.y - 26, 0, "", 21); - if (ClientPrefs.downScroll) - missTxt.y = scoreTxt.y + 26; - missTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); - missTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - missTxt.scrollFactor.set(); - add(missTxt); - missTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - - accuracyTxt = new FlxText(missTxt.x, missTxt.y - 26, 0, "", 21); - if (ClientPrefs.downScroll) - accuracyTxt.y = missTxt.y + 26; - accuracyTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); - accuracyTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - accuracyTxt.scrollFactor.set(); - add(accuracyTxt); - accuracyTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - - comboTxt = new FlxText(scoreTxt.x, scoreTxt.y + 26, 0, "", 21); - if (ClientPrefs.downScroll) - comboTxt.y = scoreTxt.y - 26; - comboTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); - comboTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - comboTxt.scrollFactor.set(); - add(comboTxt); - comboTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - - npsTxt = new FlxText(accuracyTxt.x, accuracyTxt.y - 46, 0, "", 21); - if (ClientPrefs.downScroll) - npsTxt.y = accuracyTxt.y + 46; - npsTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); - npsTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); - npsTxt.scrollFactor.set(); - add(npsTxt); - npsTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - } - if (ClientPrefs.hudType == 'Leather Engine') - { - scoreTxt = new FlxText(0, healthBarBG.y + 50, FlxG.width, "", 20); - scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); - scoreTxt.scrollFactor.set(); - scoreTxt.borderSize = 1; - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - add(scoreTxt); - } - if (ClientPrefs.hudType == 'Dave and Bambi') - { - scoreTxt = new FlxText(0, healthBarBG.y + 40, FlxG.width, "", 20); - scoreTxt.setFormat(Paths.font("comic.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - scoreTxt.scrollFactor.set(); - scoreTxt.borderSize = 1.25; - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - add(scoreTxt); - } - if (ClientPrefs.hudType == 'Psych Engine') - { - scoreTxt = new FlxText(0, healthBarBG.y + 36, FlxG.width, "", 20); - scoreTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - scoreTxt.scrollFactor.set(); - scoreTxt.borderSize = 1.25; - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - add(scoreTxt); - } - if (ClientPrefs.hudType == 'Doki Doki+') - { - scoreTxt = new FlxText(0, healthBarBG.y + 48, FlxG.width, "", 20); - scoreTxt.setFormat(Paths.font("Aller_rg.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - scoreTxt.scrollFactor.set(); - scoreTxt.borderSize = 1.25; - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - add(scoreTxt); - } - if (ClientPrefs.hudType == 'Tails Gets Trolled V4') - { - scoreTxt = new FlxText(0, healthBarBG.y + 48, FlxG.width, "", 20); - scoreTxt.setFormat(Paths.font("calibri.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - scoreTxt.scrollFactor.set(); - scoreTxt.borderSize = 1.25; - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - add(scoreTxt); - } - if (ClientPrefs.hudType == 'VS Impostor') - { - scoreTxt = new FlxText(0, healthBarBG.y + 36, FlxG.width, "", 20); - scoreTxt.scrollFactor.set(); - scoreTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - scoreTxt.scrollFactor.set(); - scoreTxt.borderSize = 1.25; - scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; - add(scoreTxt); - } - if (ClientPrefs.hideScore || ClientPrefs.showcaseMode) { - scoreTxt.destroy(); - healthBarBG.visible = false; - healthBar.visible = false; - iconP2.visible = iconP1.visible = false; - } - if (!ClientPrefs.charsAndBG) { - remove(dadGroup); - remove(boyfriendGroup); - remove(gfGroup); - gfGroup.destroy(); - dadGroup.destroy(); - boyfriendGroup.destroy(); - } - if (ClientPrefs.scoreTxtSize > 0 && scoreTxt != null) scoreTxt.size = ClientPrefs.scoreTxtSize; - if (!ClientPrefs.hideScore) updateScore(); - - judgementCounter = new FlxText(0, FlxG.height / 2 - (ClientPrefs.hudType != 'Box Funkin' || ClientPrefs.hudType != "Mic'd Up" ? 80 : 350), 0, "", 20); - judgementCounter.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - if (ClientPrefs.hudType == 'Box Funkin') judgementCounter.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - judgementCounter.borderSize = 2; - judgementCounter.scrollFactor.set(); - judgementCounter.visible = ClientPrefs.ratingCounter && !ClientPrefs.showcaseMode; - if (!ClientPrefs.noMarvJudge) - { - judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nMarvelous!!!: ' + marvs + '\nSicks!!: ' + sicks + '\nGoods!: ' + goods + '\nBads: ' + bads + '\nShits: ' + shits + '\nMisses: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - - if (ClientPrefs.hudType == 'Doki Doki+') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nVery Doki: ' + marvs + '\nDoki: ' + sicks + '\nGood: ' + goods + '\nOK: ' + bads + '\nNO: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - - if (ClientPrefs.hudType == 'VS Impostor') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSO SUSSY: ' + marvs + '\nSussy: ' + sicks + '\nSus: ' + goods + '\nSad: ' + bads + '\nAss: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - } - if (ClientPrefs.noMarvJudge) - { - judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSicks!!: ' + sicks + '\nGoods!: ' + goods + '\nBads: ' + bads + '\nShits: ' + shits + '\nMisses: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - - if (ClientPrefs.hudType == 'Doki Doki+') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nDoki: ' + sicks + '\nGood: ' + goods + '\nOK: ' + bads + '\nNO: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - - if (ClientPrefs.hudType == 'VS Impostor') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSussy: ' + sicks + '\nSus: ' + goods + '\nSad: ' + bads + '\nAss: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - } - judgementCounter.text += (ClientPrefs.showNPS ? '\nNPS (Max): ' + FlxStringUtil.formatMoney(nps, false) + ' (' + FlxStringUtil.formatMoney(maxNPS, false) + ')' : ''); - if (ClientPrefs.opponentRateCount) judgementCounter.text += '\n\nOpponent Hits: ' + FlxStringUtil.formatMoney(enemyHits, false) + ' / ' + FlxStringUtil.formatMoney(opponentNoteTotal, false) + ' (' + FlxMath.roundDecimal((enemyHits / opponentNoteTotal) * 100, 2) + '%)' + (ClientPrefs.showNPS ? '\nOpponent NPS (Max): ' + FlxStringUtil.formatMoney(oppNPS, false) + ' (' + FlxStringUtil.formatMoney(maxOppNPS, false) + ')' : ''); - add(judgementCounter); - - pauseWarnText = new FlxText(400, FlxG.height / 2 - 20, 0, "Pausing is disabled! Turn it back on in Settings -> Gameplay -> 'Force Disable Pausing'", 16); - pauseWarnText.cameras = [camHUD]; - pauseWarnText.scrollFactor.set(); - pauseWarnText.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - pauseWarnText.borderSize = 1.25; - pauseWarnText.x += 20; - pauseWarnText.y -= 25; - pauseWarnText.alpha = 0; - - if (cpuControlled && !ClientPrefs.showcaseMode) - { - if (ClientPrefs.hudType == 'Psych Engine') - { - botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); - botplayTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - botplayTxt.scrollFactor.set(); - botplayTxt.borderSize = 1.25; - botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; - add(botplayTxt); - if (ClientPrefs.downScroll) - botplayTxt.y = timeBarBG.y - 78; - } - if (ClientPrefs.hudType == 'JS Engine') - { - botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "Botplay Mode", 30); - botplayTxt.setFormat(Paths.font("vcr.ttf"), 30, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - botplayTxt.scrollFactor.set(); - botplayTxt.borderSize = 1.5; - botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; - add(botplayTxt); - if (ClientPrefs.downScroll) - botplayTxt.y = timeBarBG.y - 78; - } - if (ClientPrefs.hudType == 'Box Funkin') - { - botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); - botplayTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - botplayTxt.scrollFactor.set(); - botplayTxt.borderSize = 1.25; - botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; - add(botplayTxt); - if (ClientPrefs.downScroll) - botplayTxt.y = timeBarBG.y - 78; - } - if (ClientPrefs.hudType == "Mic'd Up") - { - botplayTxt = new FlxText((healthBarBG.width / 2), healthBar.y, 0, "AutoPlayCPU", 20); - botplayTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - botplayTxt.scrollFactor.set(); - botplayTxt.screenCenter(X); - botplayTxt.borderSize = 3; - botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; - add(botplayTxt); - if (ClientPrefs.downScroll) - botplayTxt.y = timeBarBG.y - 78; - } - if (ClientPrefs.hudType == 'Leather Engine') - { - botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "", 32); //yeah leather engine has no botplay text soooo - add(botplayTxt); - if (ClientPrefs.downScroll) - botplayTxt.y = timeBarBG.y - 78; - botplayTxt.visible = false; - } - if (ClientPrefs.hudType == 'Kade Engine') - { - botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); - botplayTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - botplayTxt.scrollFactor.set(); - botplayTxt.borderSize = 1.25; - botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; - add(botplayTxt); - if (ClientPrefs.downScroll) - botplayTxt.y = timeBarBG.y - 78; - } - if (ClientPrefs.hudType == 'Doki Doki+') - { - botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); - botplayTxt.setFormat(Paths.font("Aller_rg.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - botplayTxt.scrollFactor.set(); - botplayTxt.borderSize = 1.25; - botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; - add(botplayTxt); - if (ClientPrefs.downScroll) - botplayTxt.y = timeBarBG.y - 78; - } - if (ClientPrefs.hudType == 'Tails Gets Trolled V4') - { - botplayTxt = new FlxText(400, timeBarBG.y + (ClientPrefs.downScroll ? -78 : 55), FlxG.width - 800, "[BUTTPLUG]", 32); - botplayTxt.setFormat(Paths.font("calibri.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - botplayTxt.scrollFactor.set(); - botplayTxt.borderSize = 1.25; - botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; - add(botplayTxt); - if (ClientPrefs.downScroll) - botplayTxt.y = timeBarBG.y - 78; - } - if (ClientPrefs.hudType == 'Dave and Bambi') - { - botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); - botplayTxt.setFormat(Paths.font("comic.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - botplayTxt.scrollFactor.set(); - botplayTxt.borderSize = 1.25; - botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; - add(botplayTxt); - if (ClientPrefs.downScroll) - botplayTxt.y = timeBarBG.y - 78; - } - if (ClientPrefs.hudType == 'VS Impostor') - { - botplayTxt = new FlxText(400, healthBarBG.y - 55, FlxG.width - 800, "BOTPLAY", 32); - botplayTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - botplayTxt.scrollFactor.set(); - botplayTxt.borderSize = 1.25; - botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; - add(botplayTxt); - if (ClientPrefs.downScroll) - { - botplayTxt.y = timeBarBG.y - 78; - } - } - } - if (ClientPrefs.communityGameBot || ClientPrefs.showcaseMode && botplayTxt != null) botplayTxt.destroy(); - - laneunderlayOpponent.cameras = [camHUD]; - laneunderlay.cameras = [camHUD]; - strumLineNotes.cameras = [camHUD]; - grpNoteSplashes.cameras = [camHUD]; - notes.cameras = [camHUD]; - healthBar.cameras = [camHUD]; - healthBarBG.cameras = [camHUD]; - iconP1.cameras = [camHUD]; - iconP2.cameras = [camHUD]; - EngineWatermark.cameras = [camHUD]; - judgementCounter.cameras = [camHUD]; - scoreTxt.cameras = [camHUD]; - if(ClientPrefs.hudType == "Mic'd Up" || ClientPrefs.hudType == 'Box Funkin') - { - missTxt.cameras = [camHUD]; - accuracyTxt.cameras = [camHUD]; - npsTxt.cameras = [camHUD]; - comboTxt.cameras = [camHUD]; - } - if (botplayTxt != null) botplayTxt.cameras = [camHUD]; - timeBar.cameras = [camHUD]; - timeBarBG.cameras = [camHUD]; - timeTxt.cameras = [camHUD]; - timePercentTxt.cameras = [camHUD]; - doof.cameras = [camHUD]; - - #if android - addAndroidControls(); - androidControls.visible = false; - #end - - // if (SONG.song == 'South') - // FlxG.camera.alpha = 0.7; - // UI_camera.zoom = 1; - - // cameras = [FlxG.cameras.list[1]]; - startingSong = true; - // WINDOW TITLE POG - MusicBeatState.windowNameSuffix = " - " + SONG.song + " " + (isStoryMode ? "(Story Mode)" : "(Freeplay)"); - - #if LUA_ALLOWED - for (notetype in noteTypeMap.keys()) - { - startLuasOnFolder(SUtil.getPath() + 'custom_notetypes/' + notetype + '.lua'); - } - for (event in eventPushedMap.keys()) - { - startLuasOnFolder(SUtil.getPath() + 'custom_events/' + event + '.lua'); - } - #end - noteTypeMap.clear(); - noteTypeMap = null; - eventPushedMap.clear(); - eventPushedMap = null; - - if(eventNotes.length > 1) - { - for (event in eventNotes) event.strumTime -= eventNoteEarlyTrigger(event); - eventNotes.sort(sortByTime); - } - - // SONG SPECIFIC SCRIPTS - #if LUA_ALLOWED - var filesPushed:Array = []; - var foldersToCheck:Array = [SUtil.getPath() + Paths.getPreloadPath('data/' + Paths.formatToSongPath(SONG.song) + '/')]; - - #if MODS_ALLOWED - foldersToCheck.insert(0, Paths.mods('data/' + Paths.formatToSongPath(SONG.song) + '/')); - if(Paths.currentModDirectory != null && Paths.currentModDirectory.length > 0) - foldersToCheck.insert(0, Paths.mods(Paths.currentModDirectory + '/data/' + Paths.formatToSongPath(SONG.song) + '/')); - - for(mod in Paths.getGlobalMods()) - foldersToCheck.insert(0, Paths.mods(mod + '/data/' + Paths.formatToSongPath(SONG.song) + '/' ));// using push instead of insert because these should run after everything else - #end - - for (folder in foldersToCheck) - { - if(FileSystem.exists(folder)) - { - for (file in FileSystem.readDirectory(folder)) - { - if(file.endsWith('.lua') && !filesPushed.contains(file)) - { - luaArray.push(new FunkinLua(folder + file)); - filesPushed.push(file); - } - } - } - } - #end - - var daSong:String = Paths.formatToSongPath(curSong); - if (isStoryMode && !seenCutscene) - { - switch (daSong) - { - case "monster": - var whiteScreen:FlxSprite = new FlxSprite(0, 0).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.WHITE); - add(whiteScreen); - whiteScreen.scrollFactor.set(); - whiteScreen.blend = ADD; - camHUD.visible = false; - snapCamFollowToPos(dad.getMidpoint().x + 150, dad.getMidpoint().y - 100); - inCutscene = true; - - FlxTween.tween(whiteScreen, {alpha: 0}, 1, { - startDelay: 0.1, - ease: FlxEase.linear, - onComplete: function(twn:FlxTween) - { - camHUD.visible = true; - remove(whiteScreen); - startCountdown(); - } - }); - FlxG.sound.play(Paths.soundRandom('thunder_', 1, 2)); - if(gf != null) gf.playAnim('scared', true); - boyfriend.playAnim('scared', true); - - case "winter-horrorland": - var blackScreen:FlxSprite = new FlxSprite().makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK); - add(blackScreen); - blackScreen.scrollFactor.set(); - camHUD.visible = false; - inCutscene = true; - - FlxTween.tween(blackScreen, {alpha: 0}, 0.7, { - ease: FlxEase.linear, - onComplete: function(twn:FlxTween) { - remove(blackScreen); - } - }); - FlxG.sound.play(Paths.sound('Lights_Turn_On')); - snapCamFollowToPos(400, -2050); - FlxG.camera.focusOn(camFollow); - 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' | 'roses' | 'thorns': - if(daSong == 'roses') FlxG.sound.play(Paths.sound('ANGRY')); - schoolIntro(doof); - - case 'ugh' | 'guns' | 'stress': - tankIntro(); - - default: - startCountdown(); - } - seenCutscene = true; - } - else - { - startCountdown(); - } - RecalculateRating(); - - //PRECACHING MISS SOUNDS BECAUSE I THINK THEY CAN LAG PEOPLE AND FUCK THEM UP IDK HOW HAXE WORKS - if (hitSoundString != "none") - hitsound = FlxG.sound.load(Paths.sound("hitsounds/" + Std.string(hitSoundString).toLowerCase())); - if (hitSoundString == 'Randomized') - { - hitsound = FlxG.sound.load(Paths.sound("hitsounds/" + 'osu!mania')); - hitsound2 = FlxG.sound.load(Paths.sound("hitsounds/" + 'dave and bambi')); - hitsound3 = FlxG.sound.load(Paths.sound("hitsounds/" + 'indie cross')); - hitsound4 = FlxG.sound.load(Paths.sound("hitsounds/" + 'snap')); - hitsound5 = FlxG.sound.load(Paths.sound("hitsounds/" + 'clap')); - hitsound6 = FlxG.sound.load(Paths.sound("hitsounds/" + 'generic click')); - hitsound7 = FlxG.sound.load(Paths.sound("hitsounds/" + 'keyboard click')); - hitsound8 = FlxG.sound.load(Paths.sound("hitsounds/" + 'vine boom')); - hitsound9 = FlxG.sound.load(Paths.sound("hitsounds/" + 'adofai')); - hitsound10 = FlxG.sound.load(Paths.sound("hitsounds/" + 'discord ping')); - hitsound11 = FlxG.sound.load(Paths.sound("hitsounds/" + "i'm spongebob!")); - } - if(ClientPrefs.hitsoundVolume > 0) precacheList.set('hitsound', 'sound'); - if(ClientPrefs.hitsoundVolume > 0 && hitSoundString == 'Randomized') - { - precacheList.set('hitsound', 'sound'); - precacheList.set('hitsound2', 'sound'); - precacheList.set('hitsound3', 'sound'); - precacheList.set('hitsound4', 'sound'); - precacheList.set('hitsound5', 'sound'); - precacheList.set('hitsound6', 'sound'); - precacheList.set('hitsound7', 'sound'); - precacheList.set('hitsound8', 'sound'); - precacheList.set('hitsound9', 'sound'); - precacheList.set('hitsound10', 'sound'); - precacheList.set('hitsound11', 'sound'); - hitsound.volume = ClientPrefs.hitsoundVolume; - hitsound.pitch = playbackRate; - hitsound2.volume = ClientPrefs.hitsoundVolume; - hitsound2.pitch = playbackRate; - hitsound3.volume = ClientPrefs.hitsoundVolume; - hitsound3.pitch = playbackRate; - hitsound4.volume = ClientPrefs.hitsoundVolume; - hitsound4.pitch = playbackRate; - hitsound5.volume = ClientPrefs.hitsoundVolume; - hitsound5.pitch = playbackRate; - hitsound6.volume = ClientPrefs.hitsoundVolume; - hitsound6.pitch = playbackRate; - hitsound7.volume = ClientPrefs.hitsoundVolume; - hitsound7.pitch = playbackRate; - hitsound8.volume = ClientPrefs.hitsoundVolume; - hitsound8.pitch = playbackRate; - hitsound9.volume = ClientPrefs.hitsoundVolume; - hitsound9.pitch = playbackRate; - hitsound10.volume = ClientPrefs.hitsoundVolume; - hitsound10.pitch = playbackRate; - hitsound11.volume = ClientPrefs.hitsoundVolume; - hitsound11.pitch = playbackRate; - } - hitsound.volume = ClientPrefs.hitsoundVolume; - hitsound.pitch = playbackRate; - precacheList.set('missnote1', 'sound'); - precacheList.set('missnote2', 'sound'); - precacheList.set('missnote3', 'sound'); - - if (PauseSubState.songName != null) { - precacheList.set(PauseSubState.songName, 'music'); - } else if(ClientPrefs.pauseMusic != 'None') { - precacheList.set(Paths.formatToSongPath(ClientPrefs.pauseMusic), 'music'); - } - - precacheList.set('alphabet', 'image'); - - #if desktop - // Updating Discord Rich Presence. - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); - #end - - - if(!ClientPrefs.controllerMode) - { - FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress); - FlxG.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyRelease); - } - callOnLuas('onCreatePost', []); - - super.create(); - - if(cpuControlled && ClientPrefs.randomBotplayText && ClientPrefs.hudType != 'Leather Engine' && botplayTxt != null) - { - botplayTxt.text = theListBotplay[FlxG.random.int(0, theListBotplay.length - 1)]; - } - - cacheCountdown(); - if (ClientPrefs.ratesAndCombo) cachePopUpScore(); //Caching the ratings is unnecessary if you turn off rating popups - for (key => type in precacheList) - { - //trace('Key $key is type $type'); - switch(type) - { - case 'image': - Paths.image(key); - case 'sound': - Paths.sound(key); - case 'music': - Paths.music(key); - } - } - if (!ClientPrefs.memLeaks) - { - Paths.clearUnusedMemory(); - } - - CustomFadeTransition.nextCamera = camOther; - if(eventNotes.length < 1) checkEventNote(); - } - - #if (!flash && sys) - public var runtimeShaders:Map> = new Map>(); - public function createRuntimeShader(name:String):FlxRuntimeShader - { - if(!ClientPrefs.shaders) return new FlxRuntimeShader(); - - #if (!flash && MODS_ALLOWED && sys) - if(!runtimeShaders.exists(name) && !initLuaShader(name)) - { - FlxG.log.warn('Shader $name is missing!'); - return new FlxRuntimeShader(); - } - - var arr:Array = runtimeShaders.get(name); - return new FlxRuntimeShader(arr[0], arr[1]); - #else - FlxG.log.warn("Platform unsupported for Runtime Shaders!"); - return null; - #end - } - - #if !android - public function initLuaShader(name:String, ?glslVersion:Int = 120) - #else - public function initLuaShader(name:String, ?glslVersion:Int = 100) - #end - { - if(!ClientPrefs.shaders) return false; - - if(runtimeShaders.exists(name)) - { - FlxG.log.warn('Shader $name was already initialized!'); - return true; - } - - var foldersToCheck:Array = [Paths.mods('shaders/')]; - if(Paths.currentModDirectory != null && Paths.currentModDirectory.length > 0) - foldersToCheck.insert(0, Paths.mods(Paths.currentModDirectory + '/shaders/')); - - for(mod in Paths.getGlobalMods()) - foldersToCheck.insert(0, Paths.mods(mod + '/shaders/')); - - for (folder in foldersToCheck) - { - if(FileSystem.exists(folder)) - { - var frag:String = folder + name + '.frag'; - var vert:String = folder + name + '.vert'; - var found:Bool = false; - if(FileSystem.exists(frag)) - { - frag = File.getContent(frag); - found = true; - } - else frag = null; - - if (FileSystem.exists(vert)) - { - vert = File.getContent(vert); - found = true; - } - else vert = null; - - if(found) - { - runtimeShaders.set(name, [frag, vert]); - //trace('Found shader $name!'); - return true; - } - } - } - FlxG.log.warn('Missing shader $name .frag AND .vert files!'); - return false; - } - #end - - function set_songSpeed(value:Float):Float - { - if(generatedMusic) - { - var ratio:Float = value / songSpeed; //funny word huh - if (ratio != 1) - { - for (note in notes){ - if (note == null) - continue; - note.resizeByRatio(ratio); - } - for (note in unspawnNotes){ - if (note == null) - continue; - note.resizeByRatio(ratio); - } - } - } - songSpeed = value; - noteKillOffset = 350 / songSpeed; - return value; - } - - function set_playbackRate(value:Float):Float - { - if(generatedMusic) - { - if(vocals != null) vocals.pitch = value; - FlxG.sound.music.pitch = value; - } - playbackRate = value; - FlxAnimationController.globalSpeed = value; - trace('Anim speed: ' + FlxAnimationController.globalSpeed); - Conductor.safeZoneOffset = (ClientPrefs.safeFrames / 60) * 1000 * value; - setOnLuas('playbackRate', playbackRate); - return value; - } - - public function addTextToDebug(text:String, color:FlxColor) { - #if LUA_ALLOWED - luaDebugGroup.forEachAlive(function(spr:DebugLuaText) { - spr.y += 20; - }); - - if(luaDebugGroup.members.length > 34) { - var blah = luaDebugGroup.members[34]; - blah.destroy(); - luaDebugGroup.remove(blah); - } - luaDebugGroup.insert(0, new DebugLuaText(text, luaDebugGroup, color)); - #end - } - - public function reloadHealthBarColors() { - if (!opponentChart) healthBar.createFilledBar(FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), - FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2])); - else healthBar.createFilledBar(FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2]), - FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])); - - healthBar.updateBar(); - } - - public function addCharacterToList(newCharacter:String, type:Int) { - switch(type) { - case 0: - if(!boyfriendMap.exists(newCharacter)) { - var newBoyfriend:Boyfriend = new Boyfriend(0, 0, newCharacter); - boyfriendMap.set(newCharacter, newBoyfriend); - boyfriendGroup.add(newBoyfriend); - startCharacterPos(newBoyfriend); - newBoyfriend.alpha = 0.00001; - startCharacterLua(newBoyfriend.curCharacter); - } - - case 1: - if(!dadMap.exists(newCharacter)) { - var newDad:Character = new Character(0, 0, newCharacter); - dadMap.set(newCharacter, newDad); - dadGroup.add(newDad); - startCharacterPos(newDad, true); - newDad.alpha = 0.00001; - startCharacterLua(newDad.curCharacter); - } - - case 2: - if(gf != null && !gfMap.exists(newCharacter)) { - var newGf:Character = new Character(0, 0, newCharacter); - newGf.scrollFactor.set(0.95, 0.95); - gfMap.set(newCharacter, newGf); - gfGroup.add(newGf); - startCharacterPos(newGf); - newGf.alpha = 0.00001; - startCharacterLua(newGf.curCharacter); - } - } - } - - function startCharacterLua(name:String) - { - #if LUA_ALLOWED - var doPush:Bool = false; - var luaFile:String = 'characters/' + name + '.lua'; - #if MODS_ALLOWED - if(FileSystem.exists(Paths.modFolders(luaFile))) { - luaFile = Paths.modFolders(luaFile); - doPush = true; - } else { - luaFile = SUtil.getPath() + Paths.getPreloadPath(luaFile); - if(FileSystem.exists(luaFile)) { - doPush = true; - } - } - #else - luaFile = Paths.getPreloadPath(luaFile); - if(Assets.exists(luaFile)) { - doPush = true; - } - #end - - if(doPush) - { - for (script in luaArray) - { - if(script.scriptName == luaFile) return; - } - luaArray.push(new FunkinLua(luaFile)); - } - #end - } - - public function addShaderToCamera(cam:String,effect:Dynamic){//STOLE FROM ANDROMEDA // actually i got it from old psych engine - - - - switch(cam.toLowerCase()) { - case 'camhud' | 'hud': - camHUDShaders.push(effect); - var newCamEffects:Array=[]; // IT SHUTS HAXE UP IDK WHY BUT WHATEVER IDK WHY I CANT JUST ARRAY - for(i in camHUDShaders){ - newCamEffects.push(new ShaderFilter(i.shader)); - } - camHUD.setFilters(newCamEffects); - case 'camother' | 'other': - camOtherShaders.push(effect); - var newCamEffects:Array=[]; // IT SHUTS HAXE UP IDK WHY BUT WHATEVER IDK WHY I CANT JUST ARRAY - for(i in camOtherShaders){ - newCamEffects.push(new ShaderFilter(i.shader)); - } - camOther.setFilters(newCamEffects); - case 'camgame' | 'game': - camGameShaders.push(effect); - var newCamEffects:Array=[]; // IT SHUTS HAXE UP IDK WHY BUT WHATEVER IDK WHY I CANT JUST ARRAY - for(i in camGameShaders){ - newCamEffects.push(new ShaderFilter(i.shader)); - } - camGame.setFilters(newCamEffects); - default: - if(modchartSprites.exists(cam)) { - Reflect.setProperty(modchartSprites.get(cam),"shader",effect.shader); - } else if(modchartTexts.exists(cam)) { - Reflect.setProperty(modchartTexts.get(cam),"shader",effect.shader); - } else { - var OBJ = Reflect.getProperty(PlayState.instance,cam); - Reflect.setProperty(OBJ,"shader", effect.shader); - } - - - - - } - - - - - } - - public function removeShaderFromCamera(cam:String,effect:ShaderEffect){ - - - switch(cam.toLowerCase()) { - case 'camhud' | 'hud': - camHUDShaders.remove(effect); - var newCamEffects:Array=[]; - for(i in camHUDShaders){ - newCamEffects.push(new ShaderFilter(i.shader)); - } - camHUD.setFilters(newCamEffects); - case 'camother' | 'other': - camOtherShaders.remove(effect); - var newCamEffects:Array=[]; - for(i in camOtherShaders){ - newCamEffects.push(new ShaderFilter(i.shader)); - } - camOther.setFilters(newCamEffects); - default: - if(modchartSprites.exists(cam)) { - Reflect.setProperty(modchartSprites.get(cam),"shader",null); - } else if(modchartTexts.exists(cam)) { - Reflect.setProperty(modchartTexts.get(cam),"shader",null); - } else { - var OBJ = Reflect.getProperty(PlayState.instance,cam); - Reflect.setProperty(OBJ,"shader", null); - } - - } - - - } - - - - public function clearShaderFromCamera(cam:String){ - - - switch(cam.toLowerCase()) { - case 'camhud' | 'hud': - camHUDShaders = []; - var newCamEffects:Array=[]; - camHUD.setFilters(newCamEffects); - case 'camother' | 'other': - camOtherShaders = []; - var newCamEffects:Array=[]; - camOther.setFilters(newCamEffects); - case 'camgame' | 'game': - camGameShaders = []; - var newCamEffects:Array=[]; - camGame.setFilters(newCamEffects); - default: - camGameShaders = []; - var newCamEffects:Array=[]; - camGame.setFilters(newCamEffects); - } - - - } - - public function getLuaObject(tag:String, text:Bool=true):FlxSprite { - if(modchartSprites.exists(tag)) return modchartSprites.get(tag); - if(text && modchartTexts.exists(tag)) return modchartTexts.get(tag); - if(variables.exists(tag)) return variables.get(tag); - return null; - } - - function startCharacterPos(char:Character, ?gfCheck:Bool = false) { - if(gfCheck && char.curCharacter.startsWith('gf')) { //IF DAD IS GIRLFRIEND, HE GOES TO HER POSITION - char.setPosition(GF_X, GF_Y); - char.scrollFactor.set(0.95, 0.95); - char.danceEveryNumBeats = 2; - } - char.x += char.positionArray[0]; - char.y += char.positionArray[1]; - } - - public function startVideo(name:String) - { - #if VIDEOS_ALLOWED - inCutscene = true; - - var filepath:String = Paths.video(name); - #if sys - if(!FileSystem.exists(filepath)) - #else - if(!OpenFlAssets.exists(filepath)) - #end - { - FlxG.log.warn('Couldnt find video file: ' + name); - startAndEnd(); - return; - } - - var video:MP4Handler = new MP4Handler(); - #if (hxCodec < "3.0.0") - video.playVideo(filepath); - video.finishCallback = function() - { - startAndEnd(); - return; - } - #else - video.play(filepath); - video.onEndReached.add(function(){ - video.dispose(); - startAndEnd(); - return; - }); - #end - #else - FlxG.log.warn('Platform not supported!'); - startAndEnd(); - return; - #end - } - - function startAndEnd() - { - if(endingSong) - endSong(); - else - startCountdown(); - } - - var dialogueCount:Int = 0; - public var psychDialogue:DialogueBoxPsych; - //You don't have to add a song, just saying. You can just do "startDialogue(dialogueJson);" and it should work - public function startDialogue(dialogueFile:DialogueFile, ?song:String = null):Void - { - // TO DO: Make this more flexible, maybe? - if(psychDialogue != null) return; - - if(dialogueFile.dialogue.length > 0) { - inCutscene = true; - precacheList.set('dialogue', 'sound'); - precacheList.set('dialogueClose', 'sound'); - psychDialogue = new DialogueBoxPsych(dialogueFile, song); - psychDialogue.scrollFactor.set(); - if(endingSong) { - psychDialogue.finishThing = function() { - psychDialogue = null; - endSong(); - } - } else { - psychDialogue.finishThing = function() { - psychDialogue = null; - startCountdown(); - } - } - psychDialogue.nextDialogueThing = startNextDialogue; - psychDialogue.skipDialogueThing = skipDialogue; - psychDialogue.cameras = [camHUD]; - add(psychDialogue); - } else { - FlxG.log.warn('Your dialogue file is badly formatted!'); - if(endingSong) { - endSong(); - } else { - startCountdown(); - } - } - } - - public function changeTheSettingsBitch() { - healthGain = ClientPrefs.getGameplaySetting('healthgain', 1); - healthLoss = ClientPrefs.getGameplaySetting('healthloss', 1); - hpDrainLevel = ClientPrefs.getGameplaySetting('drainlevel', 1); - instakillOnMiss = ClientPrefs.getGameplaySetting('instakill', false); - sickOnly = ClientPrefs.getGameplaySetting('onlySicks', false); - practiceMode = ClientPrefs.getGameplaySetting('practice', false); - cpuControlled = ClientPrefs.getGameplaySetting('botplay', false); - opponentChart = ClientPrefs.getGameplaySetting('opponentplay', false); - bothsides = ClientPrefs.getGameplaySetting('bothSides', false); - trollingMode = ClientPrefs.getGameplaySetting('thetrollingever', false); - opponentDrain = ClientPrefs.getGameplaySetting('opponentdrain', false); - randomMode = ClientPrefs.getGameplaySetting('randommode', false); - flip = ClientPrefs.getGameplaySetting('flip', false); - stairs = ClientPrefs.getGameplaySetting('stairmode', false); - waves = ClientPrefs.getGameplaySetting('wavemode', false); - oneK = ClientPrefs.getGameplaySetting('onekey', false); - randomSpeedThing = ClientPrefs.getGameplaySetting('randomspeed', false); - trollingMode = ClientPrefs.getGameplaySetting('thetrollingever', false); - jackingtime = ClientPrefs.getGameplaySetting('jacks', 0); - playbackRate = ClientPrefs.getGameplaySetting('songspeed', 1); - songSpeedType = ClientPrefs.getGameplaySetting('scrolltype','multiplicative'); - - switch(songSpeedType) - { - case "multiplicative": - songSpeed = SONG.speed * ClientPrefs.getGameplaySetting('scrollspeed', 1); - case "constant": - songSpeed = ClientPrefs.getGameplaySetting('scrollspeed', 1); - } - } - - function schoolIntro(?dialogueBox:DialogueBox):Void - { - inCutscene = true; - var black:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); - black.scrollFactor.set(); - add(black); - - var red:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, 0xFFff1b31); - red.scrollFactor.set(); - - var senpaiEvil:FlxSprite = new FlxSprite(); - senpaiEvil.frames = Paths.getSparrowAtlas('weeb/senpaiCrazy'); - senpaiEvil.animation.addByPrefix('idle', 'Senpai Pre Explosion', 24, false); - senpaiEvil.setGraphicSize(Std.int(senpaiEvil.width * 6)); - senpaiEvil.scrollFactor.set(); - senpaiEvil.updateHitbox(); - senpaiEvil.screenCenter(); - senpaiEvil.x += 300; - - var songName:String = Paths.formatToSongPath(SONG.song); - if (songName == 'roses' || songName == 'thorns') - { - remove(black); - - if (songName == 'thorns') - { - add(red); - camHUD.visible = false; - } - } - - new FlxTimer().start(0.3, function(tmr:FlxTimer) - { - black.alpha -= 0.15; - - if (black.alpha > 0) - { - tmr.reset(0.3); - } - else - { - if (dialogueBox != null) - { - if (Paths.formatToSongPath(SONG.song) == 'thorns') - { - add(senpaiEvil); - senpaiEvil.alpha = 0; - new FlxTimer().start(0.3, function(swagTimer:FlxTimer) - { - senpaiEvil.alpha += 0.15; - if (senpaiEvil.alpha < 1) - { - swagTimer.reset(); - } - else - { - senpaiEvil.animation.play('idle'); - FlxG.sound.play(Paths.sound('Senpai_Dies'), 1, false, null, true, function() - { - remove(senpaiEvil); - remove(red); - FlxG.camera.fade(FlxColor.WHITE, 0.01, true, function() - { - add(dialogueBox); - camHUD.visible = true; - }, true); - }); - new FlxTimer().start(3.2, function(deadTime:FlxTimer) - { - FlxG.camera.fade(FlxColor.WHITE, 1.6, false); - }); - } - }); - } - else - { - add(dialogueBox); - } - } - else - startCountdown(); - - remove(black); - } - }); - } - - function camPanRoutine(anim:String = 'singUP', who:String = 'bf'):Void { - if (SONG.notes[curSection] != null) - { - var fps:Float = FlxG.updateFramerate; - final bfCanPan:Bool = SONG.notes[curSection].mustHitSection; - final dadCanPan:Bool = !SONG.notes[curSection].mustHitSection; - var clear:Bool = false; - switch (who) { - case 'bf': clear = bfCanPan; - case 'oppt': clear = dadCanPan; - } - //FlxG.elapsed is stinky poo poo for this, it just makes it look jank as fuck - if (clear) { - if (fps == 0) fps = 1; - switch (anim.split('-')[0]) - { - case 'singUP': moveCamTo[1] = -40*ClientPrefs.panIntensity*240/fps; - case 'singDOWN': moveCamTo[1] = 40*ClientPrefs.panIntensity*240/fps; - case 'singLEFT': moveCamTo[0] = -40*ClientPrefs.panIntensity*240/fps; - case 'singRIGHT': moveCamTo[0] = 40*ClientPrefs.panIntensity*240/fps; - } - } - } - } - - - function tankIntro() - { - var cutsceneHandler:CutsceneHandler = new CutsceneHandler(); - - var songName:String = Paths.formatToSongPath(SONG.song); - dadGroup.alpha = 0.00001; - camHUD.visible = false; - //inCutscene = true; //this would stop the camera movement, oops - - var tankman:FlxSprite = new FlxSprite(-20, 320); - tankman.frames = Paths.getSparrowAtlas('cutscenes/' + songName); - tankman.antialiasing = ClientPrefs.globalAntialiasing; - addBehindDad(tankman); - cutsceneHandler.push(tankman); - - var tankman2:FlxSprite = new FlxSprite(16, 312); - tankman2.antialiasing = ClientPrefs.globalAntialiasing; - tankman2.alpha = 0.000001; - cutsceneHandler.push(tankman2); - var gfDance:FlxSprite = new FlxSprite(gf.x - 107, gf.y + 140); - gfDance.antialiasing = ClientPrefs.globalAntialiasing; - cutsceneHandler.push(gfDance); - var gfCutscene:FlxSprite = new FlxSprite(gf.x - 104, gf.y + 122); - gfCutscene.antialiasing = ClientPrefs.globalAntialiasing; - cutsceneHandler.push(gfCutscene); - var picoCutscene:FlxSprite = new FlxSprite(gf.x - 849, gf.y - 264); - picoCutscene.antialiasing = ClientPrefs.globalAntialiasing; - cutsceneHandler.push(picoCutscene); - var boyfriendCutscene:FlxSprite = new FlxSprite(boyfriend.x + 5, boyfriend.y + 20); - boyfriendCutscene.antialiasing = ClientPrefs.globalAntialiasing; - cutsceneHandler.push(boyfriendCutscene); - - cutsceneHandler.finishCallback = function() - { - var timeForStuff:Float = Conductor.crochet / 1000 * 4.5; - FlxG.sound.music.fadeOut(timeForStuff); - FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom}, timeForStuff, {ease: FlxEase.quadInOut}); - moveCamera(true); - startCountdown(); - - dadGroup.alpha = 1; - camHUD.visible = true; - boyfriend.animation.finishCallback = null; - gf.animation.finishCallback = null; - gf.dance(); - }; - - camFollow.set(dad.x + 280, dad.y + 170); - switch(songName) - { - case 'ugh': - cutsceneHandler.endTime = 12; - cutsceneHandler.music = 'DISTORTO'; - precacheList.set('wellWellWell', 'sound'); - precacheList.set('killYou', 'sound'); - precacheList.set('bfBeep', 'sound'); - - var wellWellWell:FlxSound = new FlxSound().loadEmbedded(Paths.sound('wellWellWell')); - FlxG.sound.list.add(wellWellWell); - - tankman.animation.addByPrefix('wellWell', 'TANK TALK 1 P1', 24, false); - tankman.animation.addByPrefix('killYou', 'TANK TALK 1 P2', 24, false); - tankman.animation.play('wellWell', true); - FlxG.camera.zoom *= 1.2; - - // Well well well, what do we got here? - cutsceneHandler.timer(0.1, function() - { - wellWellWell.play(true); - }); - - // Move camera to BF - cutsceneHandler.timer(3, function() - { - camFollow.x += 750; - camFollow.y += 100; - }); - - // Beep! - cutsceneHandler.timer(4.5, function() - { - boyfriend.playAnim('singUP', true); - boyfriend.specialAnim = true; - FlxG.sound.play(Paths.sound('bfBeep')); - }); - - // Move camera to Tankman - cutsceneHandler.timer(6, function() - { - camFollow.x -= 750; - camFollow.y -= 100; - - // We should just kill you but... what the hell, it's been a boring day... let's see what you've got! - tankman.animation.play('killYou', true); - FlxG.sound.play(Paths.sound('killYou')); - }); - - case 'guns': - cutsceneHandler.endTime = 11.5; - cutsceneHandler.music = 'DISTORTO'; - tankman.x += 40; - tankman.y += 10; - precacheList.set('tankSong2', 'sound'); - - var tightBars:FlxSound = new FlxSound().loadEmbedded(Paths.sound('tankSong2')); - FlxG.sound.list.add(tightBars); - - tankman.animation.addByPrefix('tightBars', 'TANK TALK 2', 24, false); - tankman.animation.play('tightBars', true); - boyfriend.animation.curAnim.finish(); - - cutsceneHandler.onStart = function() - { - tightBars.play(true); - FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom * 1.2}, 4, {ease: FlxEase.quadInOut}); - FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom * 1.2 * 1.2}, 0.5, {ease: FlxEase.quadInOut, startDelay: 4}); - FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom * 1.2}, 1, {ease: FlxEase.quadInOut, startDelay: 4.5}); - }; - - cutsceneHandler.timer(4, function() - { - gf.playAnim('sad', true); - gf.animation.finishCallback = function(name:String) - { - gf.playAnim('sad', true); - }; - }); - - case 'stress': - cutsceneHandler.endTime = 35.5; - tankman.x -= 54; - tankman.y -= 14; - gfGroup.alpha = 0.00001; - boyfriendGroup.alpha = 0.00001; - camFollow.set(dad.x + 400, dad.y + 170); - FlxTween.tween(FlxG.camera, {zoom: 0.9 * 1.2}, 1, {ease: FlxEase.quadInOut}); - foregroundSprites.forEach(function(spr:BGSprite) - { - spr.y += 100; - }); - precacheList.set('stressCutscene', 'sound'); - - tankman2.frames = Paths.getSparrowAtlas('cutscenes/stress2'); - addBehindDad(tankman2); - - if (!ClientPrefs.lowQuality) - { - gfDance.frames = Paths.getSparrowAtlas('characters/gfTankmen'); - gfDance.animation.addByPrefix('dance', 'GF Dancing at Gunpoint', 24, true); - gfDance.animation.play('dance', true); - addBehindGF(gfDance); - } - - gfCutscene.frames = Paths.getSparrowAtlas('cutscenes/stressGF'); - gfCutscene.animation.addByPrefix('dieBitch', 'GF STARTS TO TURN PART 1', 24, false); - gfCutscene.animation.addByPrefix('getRektLmao', 'GF STARTS TO TURN PART 2', 24, false); - gfCutscene.animation.play('dieBitch', true); - gfCutscene.animation.pause(); - addBehindGF(gfCutscene); - if (!ClientPrefs.lowQuality) - { - gfCutscene.alpha = 0.00001; - } - - picoCutscene.frames = AtlasFrameMaker.construct('cutscenes/stressPico'); - picoCutscene.animation.addByPrefix('anim', 'Pico Badass', 24, false); - addBehindGF(picoCutscene); - picoCutscene.alpha = 0.00001; - - boyfriendCutscene.frames = Paths.getSparrowAtlas('characters/BOYFRIEND'); - boyfriendCutscene.animation.addByPrefix('idle', 'BF idle dance', 24, false); - boyfriendCutscene.animation.play('idle', true); - boyfriendCutscene.animation.curAnim.finish(); - addBehindBF(boyfriendCutscene); - - var cutsceneSnd:FlxSound = new FlxSound().loadEmbedded(Paths.sound('stressCutscene')); - FlxG.sound.list.add(cutsceneSnd); - - tankman.animation.addByPrefix('godEffingDamnIt', 'TANK TALK 3', 24, false); - tankman.animation.play('godEffingDamnIt', true); - - var calledTimes:Int = 0; - var zoomBack:Void->Void = function() - { - var camPosX:Float = 630; - var camPosY:Float = 425; - camFollow.set(camPosX, camPosY); - camFollowPos.setPosition(camPosX, camPosY); - FlxG.camera.zoom = 0.8; - cameraSpeed = 1; - - calledTimes++; - if (calledTimes > 1) - { - foregroundSprites.forEach(function(spr:BGSprite) - { - spr.y -= 100; - }); - } - } - - cutsceneHandler.onStart = function() - { - cutsceneSnd.play(true); - }; - - cutsceneHandler.timer(15.2, function() - { - FlxTween.tween(camFollow, {x: 650, y: 300}, 1, {ease: FlxEase.sineOut}); - FlxTween.tween(FlxG.camera, {zoom: 0.9 * 1.2 * 1.2}, 2.25, {ease: FlxEase.quadInOut}); - - gfDance.visible = false; - gfCutscene.alpha = 1; - gfCutscene.animation.play('dieBitch', true); - gfCutscene.animation.finishCallback = function(name:String) - { - if(name == 'dieBitch') //Next part - { - gfCutscene.animation.play('getRektLmao', true); - gfCutscene.offset.set(224, 445); - } - else - { - gfCutscene.visible = false; - picoCutscene.alpha = 1; - picoCutscene.animation.play('anim', true); - - boyfriendGroup.alpha = 1; - boyfriendCutscene.visible = false; - boyfriend.playAnim('bfCatch', true); - boyfriend.animation.finishCallback = function(name:String) - { - if(name != 'idle') - { - boyfriend.playAnim('idle', true); - boyfriend.animation.curAnim.finish(); //Instantly goes to last frame - } - }; - - picoCutscene.animation.finishCallback = function(name:String) - { - picoCutscene.visible = false; - gfGroup.alpha = 1; - picoCutscene.animation.finishCallback = null; - }; - gfCutscene.animation.finishCallback = null; - } - }; - }); - - cutsceneHandler.timer(17.5, function() - { - zoomBack(); - }); - - cutsceneHandler.timer(19.5, function() - { - tankman2.animation.addByPrefix('lookWhoItIs', 'TANK TALK 3', 24, false); - tankman2.animation.play('lookWhoItIs', true); - tankman2.alpha = 1; - tankman.visible = false; - }); - - cutsceneHandler.timer(20, function() - { - camFollow.set(dad.x + 500, dad.y + 170); - }); - - cutsceneHandler.timer(31.2, function() - { - boyfriend.playAnim('singUPmiss', true); - boyfriend.animation.finishCallback = function(name:String) - { - if (name == 'singUPmiss') - { - boyfriend.playAnim('idle', true); - boyfriend.animation.curAnim.finish(); //Instantly goes to last frame - } - }; - - camFollow.set(boyfriend.x + 280, boyfriend.y + 200); - cameraSpeed = 12; - FlxTween.tween(FlxG.camera, {zoom: 0.9 * 1.2 * 1.2}, 0.25, {ease: FlxEase.elasticOut}); - }); - - cutsceneHandler.timer(32.2, function() - { - zoomBack(); - }); - } - } - - var startTimer:FlxTimer; - var finishTimer:FlxTimer = null; - - // For being able to mess with the sprites on Lua - public var countdownReady:FlxSprite; - public var countdownSet:FlxSprite; - public var countdownGo:FlxSprite; - public static var startOnTime:Float = 0; - - function cacheCountdown() - { - var introAssets:Map> = new Map>(); - introAssets.set('default', ['ready', 'set', 'go']); - introAssets.set('pixel', ['pixelUI/ready-pixel', 'pixelUI/set-pixel', 'pixelUI/date-pixel']); - - var introAlts:Array = introAssets.get('default'); - if (isPixelStage) introAlts = introAssets.get('pixel'); - - for (asset in introAlts) - Paths.image(asset); - - Paths.sound('intro3' + introSoundsSuffix); - Paths.sound('intro2' + introSoundsSuffix); - Paths.sound('intro1' + introSoundsSuffix); - Paths.sound('introGo' + introSoundsSuffix); - - } - - private function updateCompactNumbers():Void - { - compactUpdateFrame++; - compactCombo = formatCompactNumber(combo); - compactMaxCombo = formatCompactNumber(maxCombo); - compactScore = formatCompactNumber(songScore); - compactMisses = formatCompactNumberInt(songMisses); - compactNPS = formatCompactNumber(nps); - compactTotalPlays = formatCompactNumber(totalNotesPlayed); - } - - public static function formatCompactNumber(number:Float):String //this entire function is ai generated LMAO - { - var suffixes:Array = ['', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quattuordecillion', 'quindecillion', 'sexdecillion', 'septendecillion', 'octodecillion', 'novemdecillion', 'vigintillion', 'unvigintillion', 'duovigintillion', 'trevigintillion', 'quattuorvigintillion', 'quinvigintillion', 'sesvigintillion', 'septemvigintillion', 'octovigintillion', 'novemvigintillion', 'trigintillion', 'untrigintillion', 'duotrigintillion', 'trestrigintillion', 'quattuortrigintillion', 'quintrigintillion', 'sestrigintillion', 'septentrigintillion', 'octotrigintillion', 'noventrigintillion', 'quadragintillion', 'unquadragintillion', 'duoquadragintillion', 'trequadragintillion', 'quattuorquadragintillion', 'quinquadragintillion', 'sesquadragintillion', 'septenquadragintillion', 'octoquadragintillion', 'novenquadragintillion', 'quinquagintillion', 'unquinquagintillion', 'duoquinquagintillion', 'trequinquagintillion', 'quattuorquinquagintillion', 'quinquinquagintillion', 'sesquinquagintillion', 'septenquinquagintillion', 'octoquinquagintillion', 'novenquinquagintillion', 'sexagintillion', 'unsexagintillion', 'duosexagintillion', 'tresexagintillion', 'quattuorsexagintillion', 'quinsexagintillion', 'sesagintillion', 'septensexagintillion', 'octosexagintillion', 'novensexagintillion', 'septuagintillion', 'unseptuagintillion', 'duoseptuagintillion', 'treseptuagintillion', 'quattuorseptuagintillion', 'quinseptuagintillion', 'seseptuaintillion', 'septenseptuagintillion', 'octoseptuagintillion', 'novenseptuagintillion', 'octogintillion', 'unoctogintillion', 'duooctogintillion', 'tresoctogintillion', 'quattuoroctogintillion', 'quinoctogintillion', 'sesoctogintillion', 'septenoctogintillion', 'octooctogintillion', 'novenoctogintillion', 'nonagintillion', 'unnonagintillion', 'duononagintillion', 'tresnonagintillion', 'quattuornonagintillion', 'quinnonagintillion', 'sesnonagintillion', 'septennonagintillion', 'octononagintillion', 'novennonagintillion', 'centillion', 'uncentillion']; //Every 'illion' up to 10^308, taken straight from Conway's zillion number list - var magnitude:Int = 0; - var num:Float = number; - - while (num >= 1000.0 && magnitude < suffixes.length - 1) - { - num /= 1000.0; - magnitude++; - } - - // Use the floor value for the compact representation - var compactValue:Float = Math.floor(num * 100) / 100; - if (compactValue <= 0.001) { - return "0"; //Return 0 if compactValue = null - } else { - return compactValue + (magnitude == 0 ? "" : " ") + suffixes[magnitude]; - } - } - public static function formatCompactNumberInt(number:Int):String //this entire function is ai generated LMAO - { - var suffixes:Array = ['', 'thousand', 'million', 'billion']; //Illions up to billion, nothing higher because integers can't go past 2,147,483,647 - var magnitude:Int = 0; - var num:Float = number; - - while (num >= 1000.0 && magnitude < suffixes.length - 1) - { - num /= 1000.0; - magnitude++; - } - - // Use the floor value for the compact representation - var compactValue:Float = Math.floor(num * 100) / 100; - if (compactValue <= 0.001) { - return "0"; //Return 0 if compactValue = null - } else { - return compactValue + (magnitude == 0 ? "" : " ") + suffixes[magnitude]; - } - } - - - public function startCountdown():Void - { - if(startedCountdown) { - callOnLuas('onStartCountdown', []); - return; - } - - inCutscene = false; - var ret:Dynamic = callOnLuas('onStartCountdown', [], false); - - if (ClientPrefs.coolGameplay) - { - hueh231 = new FlxSprite(); - hueh231.frames = Paths.getSparrowAtlas('dokistuff/coolgameplay'); - hueh231.animation.addByPrefix('idle', 'Symbol', 24, true); - hueh231.animation.play('idle'); - hueh231.antialiasing = ClientPrefs.globalAntialiasing; - hueh231.scrollFactor.set(); - hueh231.setGraphicSize(Std.int(hueh231.width / FlxG.camera.zoom)); - hueh231.updateHitbox(); - hueh231.screenCenter(); - hueh231.cameras = [camGame]; - add(hueh231); - } - if (SONG.song.toLowerCase() == 'anti-cheat-song') - { - secretsong = new FlxSprite().loadGraphic(Paths.image('secretSong')); - secretsong.antialiasing = ClientPrefs.globalAntialiasing; - secretsong.scrollFactor.set(); - secretsong.setGraphicSize(Std.int(secretsong.width / FlxG.camera.zoom)); - secretsong.updateHitbox(); - secretsong.screenCenter(); - secretsong.cameras = [camGame]; - add(secretsong); - } - if (ClientPrefs.middleScroll || ClientPrefs.mobileMidScroll) - { - laneunderlayOpponent.alpha = 0; - laneunderlay.screenCenter(X); - } - - if(ret != FunkinLua.Function_Stop) { - if (skipCountdown || startOnTime > 0) skipArrowStartTween = true; - - #if android - androidControls.visible = !cpuControlled; //no need to have them visible if Botplay is on - #end - generateStaticArrows(0); - generateStaticArrows(1); - for (i in 0...opponentStrums.length) { - setOnLuas('defaultOpponentStrumX' + i, opponentStrums.members[i].x); - setOnLuas('defaultOpponentStrumY' + i, opponentStrums.members[i].y); - //if(ClientPrefs.middleScroll) opponentStrums.members[i].visible = false; - } - for (i in 0...playerStrums.length) { - setOnLuas('defaultPlayerStrumX' + i, playerStrums.members[i].x); - setOnLuas('defaultPlayerStrumY' + i, playerStrums.members[i].y); - } - /*for (i in 0...opponentStrums.length) { - setOnLuas('defaultOpponentStrumX' + i, opponentStrums.members[i].x); - setOnLuas('defaultOpponentStrumY' + i, opponentStrums.members[i].y); - //if(ClientPrefs.middleScroll) opponentStrums.members[i].visible = false; - } - */ - - startedCountdown = true; - Conductor.songPosition = -Conductor.crochet * 5; - setOnLuas('startedCountdown', true); - callOnLuas('onCountdownStarted', []); - - var swagCounter:Int = 0; - - if(startOnTime < 0) startOnTime = 0; - - if (startOnTime > 0) { - clearNotesBefore(startOnTime); - setSongTime(startOnTime - 350); - return; - } - else if (skipCountdown) - { - setSongTime(0); - return; - } - - startTimer = new FlxTimer().start(Conductor.crochet / 1000 / playbackRate, function(tmr:FlxTimer) - { - if (ClientPrefs.charsAndBG) { - if (gf != null && tmr.loopsLeft % Math.round(gfSpeed * gf.danceEveryNumBeats) == 0 && gf.animation.curAnim != null && !gf.animation.curAnim.name.startsWith("sing") && !gf.stunned) - { - gf.dance(); - } - if (tmr.loopsLeft % boyfriend.danceEveryNumBeats == 0 && boyfriend.animation.curAnim != null && !boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.stunned) - { - boyfriend.dance(); - } - if (tmr.loopsLeft % dad.danceEveryNumBeats == 0 && dad.animation.curAnim != null && !dad.animation.curAnim.name.startsWith('sing') && !dad.stunned) - { - dad.dance(); - } - } - - var introAssets:Map> = new Map>(); - introAssets.set('default', ['ready', 'set', 'go']); - introAssets.set('pixel', ['pixelUI/ready-pixel', 'pixelUI/set-pixel', 'pixelUI/date-pixel']); - - var introAlts:Array = introAssets.get('default'); - var antialias:Bool = ClientPrefs.globalAntialiasing; - if(isPixelStage) { - introAlts = introAssets.get('pixel'); - antialias = false; - } - - // head bopping for bg characters on Mall - if(curStage == 'mall') { - if(!ClientPrefs.lowQuality) - upperBoppers.dance(true); - - bottomBoppers.dance(true); - santa.dance(true); - } - - switch (swagCounter) - { - case 0: - FlxG.sound.play(Paths.sound('intro3' + introSoundsSuffix), 0.6); - case 1: - countdownReady = new FlxSprite().loadGraphic(Paths.image(introAlts[0])); - countdownReady.cameras = [camHUD]; - countdownReady.scrollFactor.set(); - countdownReady.updateHitbox(); - - if (PlayState.isPixelStage) - countdownReady.setGraphicSize(Std.int(countdownReady.width * daPixelZoom)); - - countdownReady.screenCenter(); - countdownReady.antialiasing = antialias; - insert(members.indexOf(notes), countdownReady); - FlxTween.tween(countdownReady, {/*y: countdownReady.y + 100,*/ alpha: 0}, Conductor.crochet / 1000 / playbackRate, { - ease: FlxEase.cubeInOut, - onComplete: function(twn:FlxTween) - { - remove(countdownReady); - countdownReady.destroy(); - } - }); - FlxG.sound.play(Paths.sound('intro2' + introSoundsSuffix), 0.6); - case 2: - countdownSet = new FlxSprite().loadGraphic(Paths.image(introAlts[1])); - countdownSet.cameras = [camHUD]; - countdownSet.scrollFactor.set(); - - if (PlayState.isPixelStage) - countdownSet.setGraphicSize(Std.int(countdownSet.width * daPixelZoom)); - - countdownSet.screenCenter(); - countdownSet.antialiasing = antialias; - insert(members.indexOf(notes), countdownSet); - FlxTween.tween(countdownSet, {/*y: countdownSet.y + 100,*/ alpha: 0}, Conductor.crochet / 1000 / playbackRate, { - ease: FlxEase.cubeInOut, - onComplete: function(twn:FlxTween) - { - remove(countdownSet); - countdownSet.destroy(); - } - }); - FlxG.sound.play(Paths.sound('intro1' + introSoundsSuffix), 0.6); - case 3: - countdownGo = new FlxSprite().loadGraphic(Paths.image(introAlts[2])); - countdownGo.cameras = [camHUD]; - countdownGo.scrollFactor.set(); - - if (PlayState.isPixelStage) - countdownGo.setGraphicSize(Std.int(countdownGo.width * daPixelZoom)); - - countdownGo.updateHitbox(); - - countdownGo.screenCenter(); - countdownGo.antialiasing = antialias; - insert(members.indexOf(notes), countdownGo); - FlxTween.tween(countdownGo, {/*y: countdownGo.y + 100,*/ alpha: 0}, Conductor.crochet / 1000 / playbackRate, { - ease: FlxEase.cubeInOut, - onComplete: function(twn:FlxTween) - { - remove(countdownGo); - countdownGo.destroy(); - } - }); - FlxG.sound.play(Paths.sound('introGo' + introSoundsSuffix), 0.6); - case 4: - if (SONG.songCredit != null) - { - var creditsPopup:CreditsPopUp = new CreditsPopUp(FlxG.width, 200); - creditsPopup.camera = camHUD; - creditsPopup.scrollFactor.set(); - creditsPopup.x = creditsPopup.width * -1; - add(creditsPopup); - - FlxTween.tween(creditsPopup, {x: 0}, 0.5, {ease: FlxEase.backOut, onComplete: function(tweeen:FlxTween) - { - FlxTween.tween(creditsPopup, {x: creditsPopup.width * -1} , 1, {ease: FlxEase.backIn, onComplete: function(tween:FlxTween) - { - creditsPopup.destroy(); - }, startDelay: 3}); - }}); - } - } - - notes.forEachAlive(function(note:Note) { - if(ClientPrefs.opponentStrums || !ClientPrefs.opponentStrums && ClientPrefs.mobileMidScroll || ClientPrefs.middleScroll || !note.mustPress) - { - note.alpha *= 0.35; - } - if(ClientPrefs.opponentStrums || !ClientPrefs.opponentStrums && ClientPrefs.mobileMidScroll || note.mustPress) - { - note.copyAlpha = false; - note.alpha = note.multAlpha; - if(ClientPrefs.middleScroll && !note.mustPress) { - note.alpha *= 0.35; - } - if(ClientPrefs.mobileMidScroll && !note.mustPress) { - note.alpha *= 0.35; - } - } - }); - callOnLuas('onCountdownTick', [swagCounter]); - - swagCounter += 1; - // generateSong('fresh'); - }, 5); - } - } - - public function addBehindGF(obj:FlxObject) - { - insert(members.indexOf(gfGroup), obj); - } - public function addBehindBF(obj:FlxObject) - { - insert(members.indexOf(boyfriendGroup), obj); - } - public function addBehindDad (obj:FlxObject) - { - insert(members.indexOf(dadGroup), obj); - } - - public function clearNotesBefore(time:Float) - { - var i:Int = unspawnNotes.length - 1; - while (i >= 0) { - var daNote:Note = unspawnNotes[i]; - if(daNote.strumTime - 350 < time) - { - daNote.active = false; - daNote.visible = false; - daNote.ignoreNote = true; - - if (shouldKillNotes) { - daNote.kill(); - } - //unspawnNotes.remove(daNote); - if (shouldKillNotes) { - daNote.destroy(); - } - } - --i; - } - - i = notes.length - 1; - while (i >= 0) { - var daNote:Note = notes.members[i]; - if(daNote.strumTime - 350 < time) - { - daNote.active = false; - daNote.visible = false; - daNote.ignoreNote = true; - - if (shouldKillNotes) { - daNote.kill(); - } - notes.remove(daNote, true); - if (shouldKillNotes) { - daNote.destroy(); - } - } - --i; - } - } - - public function updateScore(miss:Bool = false) - { - if (ClientPrefs.hudType == 'Kade Engine') - { - scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Combo Breaks: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) - + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Accuracy: ' + Highscore.floorDecimal(ratingPercent * 100, 2) + '%' - + ' | ' + ratingFC + ratingCool; - if (cpuControlled && !ClientPrefs.communityGameBot) - { - scoreTxt.text = 'Bot Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Botplay Mode '; - } - } - if (ClientPrefs.hudType == "Mic'd Up" || ClientPrefs.hudType == 'Box Funkin') - { - comboTxt.text = "Combo: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo); - scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : ''); - missTxt.text = "Misses: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses); - accuracyTxt.text = "Accuracy: " + Highscore.floorDecimal(ratingPercent * 100, 2) + "% | " + ratingFC + " |" + ratingCool; - npsTxt.text = "\n" + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : ''); - if (cpuControlled && !ClientPrefs.communityGameBot) - { - scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : ''); - missTxt.text = "Bot Combo: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo); - accuracyTxt.text = "" + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : ''); - npsTxt.text = "Botplay Mode"; - } - } - if (ClientPrefs.hudType == "Doki Doki+") - { - scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Breaks: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) - + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Accuracy: ' + Highscore.floorDecimal(ratingPercent * 100, 2) + '%' - + ' | ' + ratingFC + ratingCool; - if (cpuControlled && !ClientPrefs.communityGameBot) - { - scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Botplay Mode '; - } - } - if (ClientPrefs.hudType == "Dave and Bambi") - { - scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) - + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Accuracy: ' + Highscore.floorDecimal(ratingPercent * 100, 2) + '%' - + ' | ' + ratingFC; - if (cpuControlled && !ClientPrefs.communityGameBot) - { - scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Botplay Mode '; - } - } - if (ClientPrefs.hudType == "Psych Engine") - { - scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) - + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Rating: ' + ratingName - + (ratingName != '?' ? ' (${Highscore.floorDecimal(ratingPercent * 100, 2)}%) - $ratingFC' : ''); - if (cpuControlled && !ClientPrefs.communityGameBot) - { - scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | funny botplay mode!!!!!'; - } - } - if (ClientPrefs.hudType == "JS Engine") - { - scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(shownScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) - + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Rating: ' + ratingName - + (ratingName != '?' ? ' (${Highscore.floorDecimal(ratingPercent * 100, 2)}%) - $ratingFC' : ''); - if (cpuControlled && !ClientPrefs.communityGameBot) - { - scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(shownScore, false) : compactScore) - + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Botplay Mode'; - } - } - if (ClientPrefs.hudType == "Leather Engine") - { - scoreTxt.text = '< Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) - + ' ~ Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) - + ' ~ Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' ~ NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' ~ Rating: ' + ratingName - + (ratingName != '?' ? ' (${Highscore.floorDecimal(ratingPercent * 100, 2)}%) ~ $ratingFC' : ''); - if (cpuControlled && !ClientPrefs.communityGameBot) - { - scoreTxt.text = "< Bot Score: " + FlxStringUtil.formatMoney(songScore, false) - + ' ~ Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' ~ Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' ~ Botplay Mode >'; - } - } - if (ClientPrefs.hudType == "Tails Gets Trolled V4") - { - scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) - + ' | Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) - + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Rating: ' + ratingName - + (ratingName != '?' ? ' (${Highscore.floorDecimal(ratingPercent * 100, 2)}%) - $ratingFC' : ''); - if (cpuControlled && !ClientPrefs.communityGameBot) - { - scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | funny botplay mode!!!!'; - } - } - if (ClientPrefs.hudType == "VS Impostor") - { - scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Combo Breaks: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) - + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Accuracy: ' + Highscore.floorDecimal(ratingPercent * 100, 2) + '%' - + ratingFC; - if (cpuControlled && !ClientPrefs.communityGameBot) - { - scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') - + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) - + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') - + ' | Botplay Mode'; - } - } - if (ClientPrefs.healthDisplay) scoreTxt.text += ' | Health: ' + FlxMath.roundDecimal(health * 50, 2) + '%'; - - /*if(ClientPrefs.scoreZoom && !miss && !cpuControlled) - { - if(scoreTxtTween != null) { - scoreTxtTween.cancel(); - } - scoreTxt.scale.x = 1.075; - scoreTxt.scale.y = 1.075; - scoreTxtTween = FlxTween.tween(scoreTxt.scale, {x: 1, y: 1}, 0.2, { - onComplete: function(twn:FlxTween) { - scoreTxtTween = null; - } - }); - } moving this to popupscore so that it doesn't just break scoretxt*/ - callOnLuas('onUpdateScore', [miss]); - scoreTxtUpdateFrame++; - } - - public function setSongTime(time:Float) - { - if(time < 0) time = 0; - - if (ClientPrefs.songLoading) FlxG.sound.music.pause(); - if (ClientPrefs.songLoading) vocals.pause(); - - if (ClientPrefs.songLoading) FlxG.sound.music.time = time; - if (ClientPrefs.songLoading) FlxG.sound.music.pitch = playbackRate; - if (ClientPrefs.songLoading) FlxG.sound.music.play(); - - if (Conductor.songPosition <= vocals.length && ClientPrefs.songLoading) - { - vocals.time = time; - vocals.pitch = playbackRate; - } - if (ClientPrefs.songLoading) vocals.play(); - Conductor.songPosition = time; - songTime = time; - } - - function startNextDialogue() { - dialogueCount++; - callOnLuas('onNextDialogue', [dialogueCount]); - } - - function skipDialogue() { - callOnLuas('onSkipDialogue', [dialogueCount]); - } - - var previousFrameTime:Int = 0; - var lastReportedPlayheadPosition:Int = 0; - var songTime:Float = 0; - - function startSong():Void - { - startingSong = false; - - previousFrameTime = FlxG.game.ticks; - lastReportedPlayheadPosition = 0; - if (ClientPrefs.songLoading) - { - FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false); - FlxG.sound.music.pitch = playbackRate; - if (!trollingMode && SONG.song.toLowerCase() != 'anti-cheat-song' && SONG.song.toLowerCase() != 'desert bus') - { - FlxG.sound.music.onComplete = finishSong.bind(); - } - /* - if (trollingMode && ClientPrefs.trollMaxSpeed == 'Highest') - { - FlxG.sound.music.onComplete = loopSongHighest.bind(); - } - if (trollingMode && ClientPrefs.trollMaxSpeed == 'High') - { - FlxG.sound.music.onComplete = loopSongHigh.bind(); - } - if (trollingMode && ClientPrefs.trollMaxSpeed == 'Medium') - { - FlxG.sound.music.onComplete = loopSongMedium.bind(); - } - if (trollingMode && ClientPrefs.trollMaxSpeed == 'Low') - { - FlxG.sound.music.onComplete = loopSongLow.bind(); - } - if (trollingMode && ClientPrefs.trollMaxSpeed == 'Lower') - { - FlxG.sound.music.onComplete = loopSongLower.bind(); - } - if (trollingMode && ClientPrefs.trollMaxSpeed == 'Lowest') - { - FlxG.sound.music.onComplete = loopSongLowest.bind(); - } - if (trollingMode && ClientPrefs.trollMaxSpeed == 'Disabled') - { - FlxG.sound.music.onComplete = loopSongNoLimit.bind(); - } - */ - vocals.play(); - } - - if(startOnTime > 0) - { - setSongTime(startOnTime - 500); - } - startOnTime = 0; - - if(paused) { - //trace('Oopsie doopsie! Paused sound'); - if (ClientPrefs.songLoading) - { - FlxG.sound.music.pause(); - vocals.pause(); - } - } - var curTime:Float = Conductor.songPosition - ClientPrefs.noteOffset; - songPercent = (curTime / songLength); - - - // Song duration in a float, useful for the time left feature - if (ClientPrefs.lengthIntro && ClientPrefs.songLoading) FlxTween.tween(this, {songLength: FlxG.sound.music.length}, 1, {ease: FlxEase.expoOut}); - if (!ClientPrefs.lengthIntro && ClientPrefs.songLoading) songLength = FlxG.sound.music.length; //so that the timer won't just appear as 0 - if (ClientPrefs.timeBarType != 'Disabled') { - timeBar.scale.x = 0.01; - timeBarBG.scale.x = 0.01; - FlxTween.tween(timeBar, {alpha: 1, "scale.x": 1}, 1, {ease: FlxEase.expoOut}); - FlxTween.tween(timeBarBG, {alpha: 1, "scale.x": 1}, 1, {ease: FlxEase.expoOut}); - FlxTween.tween(timeTxt, {alpha: 1}, 0.5, {ease: FlxEase.circOut}); - } - FlxTween.tween(timePercentTxt, {alpha: 1}, 0.5, {ease: FlxEase.circOut}); - - - - switch(curStage) - { - case 'tank': - if(!ClientPrefs.lowQuality) tankWatchtower.dance(); - foregroundSprites.forEach(function(spr:BGSprite) - { - spr.dance(); - }); - } - - #if desktop - if (cpuControlled) detailsText = detailsText + ' (using a bot)'; - // Updating Discord Rich Presence (with Time Left) - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter(), true, songLength); - #end - setOnLuas('songLength', songLength); - callOnLuas('onSongStart', []); - } - public function lerpSongSpeed(num:Float, time:Float):Void - { - FlxTween.num(playbackRate, num, time, {onUpdate: function(tween:FlxTween){ - var ting = FlxMath.lerp(playbackRate, num, tween.percent); - if (ting != 0) //divide by 0 is a verry bad - playbackRate = ting; //why cant i just tween a variable - - if (ClientPrefs.songLoading) FlxG.sound.music.time = Conductor.songPosition; - if (ClientPrefs.songLoading && !ClientPrefs.noSyncing) resyncVocals(); - }}); - } - - var debugNum:Int = 0; - var stair:Int = 0; - private var noteTypeMap:Map = new Map(); - private var eventPushedMap:Map = new Map(); - private function generateSong(dataPath:String):Void - { - var startTime = Sys.time(); - // FlxG.log.add(ChartParser.parse()); - songSpeedType = ClientPrefs.getGameplaySetting('scrolltype','multiplicative'); - - switch(songSpeedType) - { - case "multiplicative": - songSpeed = SONG.speed * ClientPrefs.getGameplaySetting('scrollspeed', 1); - case "constant": - songSpeed = ClientPrefs.getGameplaySetting('scrollspeed', 1); - } - - Conductor.changeBPM(SONG.bpm); - - curSong = SONG.song; - - if (SONG.needsVoices && ClientPrefs.songLoading) - vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song)); - else - vocals = new FlxSound(); - - if (ClientPrefs.songLoading) vocals.pitch = playbackRate; - if (ClientPrefs.songLoading) FlxG.sound.list.add(vocals); - if (ClientPrefs.songLoading) FlxG.sound.list.add(new FlxSound().loadEmbedded(Paths.inst(PlayState.SONG.song))); - - notes = new FlxTypedGroup(); - add(notes); - notes.visible = ClientPrefs.showNotes; //that was easier than expected - - var noteData:Array = SONG.notes; - - var songName:String = Paths.formatToSongPath(SONG.song); - var file:String = Paths.json(songName + '/events'); - #if MODS_ALLOWED - if (FileSystem.exists(Paths.modsJson(songName + '/events')) || FileSystem.exists(file)) { - #else - if (OpenFlAssets.exists(file)) { - #end - var eventsData:Array = Song.loadFromJson('events', songName).events; - for (event in eventsData) //Event Notes - { - for (i in 0...event[1].length) - { - var newEventNote:Array = [event[0], event[1][i][0], event[1][i][1], event[1][i][2]]; - var subEvent:EventNote = { - strumTime: newEventNote[0] + ClientPrefs.noteOffset, - event: newEventNote[1], - value1: newEventNote[2], - value2: newEventNote[3] - }; - eventNotes.push(subEvent); - eventPushed(subEvent); - } - } - } - - for (section in noteData) - { - for (songNotes in section.sectionNotes) - { - var daStrumTime:Float = songNotes[0]; - var daNoteData:Int = 0; - if (!randomMode && !flip && !stairs && !waves) - { - daNoteData = Std.int(songNotes[1] % 4); - } - if (oneK) - { - daNoteData = 2; - } - if (randomMode) { - daNoteData = FlxG.random.int(0, 3); - } - if (flip) { - daNoteData = Std.int(Math.abs((songNotes[1] % 4) - 3)); - } - if (stairs && !waves) { - daNoteData = stair % 4; - stair++; - } - if (waves) { - switch (stair % 6) - { - case 0 | 1 | 2 | 3: - daNoteData = stair % 6; - case 4: - daNoteData = 2; - case 5: - daNoteData = 1; - } - stair++; - } - var gottaHitNote:Bool = section.mustHitSection; - - if (songNotes[1] > 3 && !opponentChart && !bothsides) - { - gottaHitNote = !section.mustHitSection; - } - if (songNotes[1] <= 3 && opponentChart && !bothsides) - { - gottaHitNote = !section.mustHitSection; - } - else if (!gottaHitNote && bothsides) - { - gottaHitNote = true; - } - - if (!gottaHitNote && !bothsides && ClientPrefs.mobileMidScroll) - { - songNotes[3] = 'Behind Note'; - } - if (gottaHitNote && !songNotes.hitCausesMiss) - { - totalNotes += 1; - } - if (!gottaHitNote) - { - opponentNoteTotal += 1; - } - - var oldNote:Note = unspawnNotes.length > 0 ? unspawnNotes[Std.int(unspawnNotes.length - 1)] : null; - - var swagNote:Note = new Note(daStrumTime, daNoteData, oldNote); - if (ClientPrefs.doubleGhost) - { - swagNote.row = Conductor.secsToRow(daStrumTime); - if(noteRows[gottaHitNote?0:1][swagNote.row]==null) - noteRows[gottaHitNote?0:1][swagNote.row]=[]; - noteRows[gottaHitNote ? 0 : 1][swagNote.row].push(swagNote); - } - swagNote.mustPress = gottaHitNote; - swagNote.sustainLength = songNotes[2]; - swagNote.gfNote = (section.gfSection && (songNotes[1]<4)); - swagNote.noteType = songNotes[3]; - if(!Std.isOfType(songNotes[3], String)) swagNote.noteType = editors.ChartingState.noteTypeList[songNotes[3]]; //Backward compatibility + compatibility with Week 7 charts - - swagNote.scrollFactor.set(); - unspawnNotes.push(swagNote); - - var floorSus:Int = Math.floor(swagNote.sustainLength / Conductor.stepCrochet); - if(floorSus > 0) { - for (susNote in 0...floorSus+1) - { - oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)]; - - var sustainNote:Note = new Note(daStrumTime + (Conductor.stepCrochet * susNote) + (Conductor.stepCrochet / FlxMath.roundDecimal(songSpeed, 2)), daNoteData, oldNote, true); - sustainNote.mustPress = gottaHitNote; - sustainNote.gfNote = (section.gfSection && (songNotes[1]<4)); - sustainNote.noteType = swagNote.noteType; - sustainNote.scrollFactor.set(); - swagNote.tail.push(sustainNote); - sustainNote.parent = swagNote; - unspawnNotes.push(sustainNote); - } - } - if(!noteTypeMap.exists(swagNote.noteType)) { - noteTypeMap.set(swagNote.noteType, true); - } - var jackNote:Note; - - if (jackingtime > 0) - { - for (i in 0...Std.int(jackingtime)) - { - jackNote = new Note(swagNote.strumTime + (15000/SONG.bpm) * (i + 1), swagNote.noteData, oldNote); - jackNote.scrollFactor.set(); - - jackNote.mustPress = swagNote.mustPress; - jackNote.sustainLength = swagNote.sustainLength; - jackNote.gfNote = swagNote.gfNote; - jackNote.noteType = swagNote.noteType; - if (ClientPrefs.doubleGhost) - { - jackNote.row = Conductor.secsToRow(daStrumTime); - if(noteRows[gottaHitNote?0:1][jackNote.row]==null) - noteRows[gottaHitNote?0:1][jackNote.row]=[]; - noteRows[gottaHitNote ? 0 : 1][jackNote.row].push(jackNote); - } - - unspawnNotes.push(jackNote); - - jackNote.mustPress = swagNote.mustPress; - - if (jackNote.mustPress) - { - jackNote.x += FlxG.width / 2; // general offset - totalNotes += 1; - } - if (!jackNote.mustPress) - { - opponentNoteTotal += 1; - } - if(!noteTypeMap.exists(jackNote.noteType)) { - noteTypeMap.set(jackNote.noteType, true); - } - } - } - } - sectionsLoaded += 1; - trace('loaded section ' + sectionsLoaded); - } - for (event in SONG.events) //Event Notes - { - for (i in 0...event[1].length) - { - var newEventNote:Array = [event[0], event[1][i][0], event[1][i][1], event[1][i][2]]; - var subEvent:EventNote = { - strumTime: newEventNote[0] + ClientPrefs.noteOffset, - event: newEventNote[1], - value1: newEventNote[2], - value2: newEventNote[3] - }; - eventNotes.push(subEvent); - eventPushed(subEvent); - } - } - - // trace(unspawnNotes.length); - // playerCounter += 1; - - var endTime = Sys.time(); - - var elapsedTime = endTime - startTime; - unspawnNotes.sort(sortByTime); - unspawnNotesCopy = unspawnNotes.copy(); - generatedMusic = true; - maxScore = totalNotes * (ClientPrefs.noMarvJudge ? 350 : 500); - var elapsedTime = endTime - startTime; - trace("Loaded chart in " + elapsedTime + " seconds"); - } - function eventPushed(event:EventNote) { - switch(event.event) { - case 'Change Character': - var charType:Int = 0; - switch(event.value1.toLowerCase()) { - case 'gf' | 'girlfriend' | '1': - charType = 2; - case 'dad' | 'opponent' | '0': - charType = 1; - default: - charType = Std.parseInt(event.value1); - if(Math.isNaN(charType)) charType = 0; - } - - var newCharacter:String = event.value2; - addCharacterToList(newCharacter, charType); - - case 'Dadbattle Spotlight': - dadbattleBlack = new BGSprite(null, -800, -400, 0, 0); - dadbattleBlack.makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK); - dadbattleBlack.alpha = 0.25; - dadbattleBlack.visible = false; - add(dadbattleBlack); - - dadbattleLight = new BGSprite('spotlight', 400, -400); - dadbattleLight.alpha = 0.375; - dadbattleLight.blend = ADD; - dadbattleLight.visible = false; - - dadbattleSmokes.alpha = 0.7; - dadbattleSmokes.blend = ADD; - dadbattleSmokes.visible = false; - add(dadbattleLight); - add(dadbattleSmokes); - - var offsetX = 200; - var smoke:BGSprite = new BGSprite('smoke', -1550 + offsetX, 660 + FlxG.random.float(-20, 20), 1.2, 1.05); - smoke.setGraphicSize(Std.int(smoke.width * FlxG.random.float(1.1, 1.22))); - smoke.updateHitbox(); - smoke.velocity.x = FlxG.random.float(15, 22); - smoke.active = true; - dadbattleSmokes.add(smoke); - var smoke:BGSprite = new BGSprite('smoke', 1550 + offsetX, 660 + FlxG.random.float(-20, 20), 1.2, 1.05); - smoke.setGraphicSize(Std.int(smoke.width * FlxG.random.float(1.1, 1.22))); - smoke.updateHitbox(); - smoke.velocity.x = FlxG.random.float(-15, -22); - smoke.active = true; - smoke.flipX = true; - dadbattleSmokes.add(smoke); - - - case 'Philly Glow': - blammedLightsBlack = new FlxSprite(FlxG.width * -0.5, FlxG.height * -0.5).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK); - blammedLightsBlack.visible = false; - insert(members.indexOf(phillyStreet), blammedLightsBlack); - - phillyWindowEvent = new BGSprite('philly/window', phillyWindow.x, phillyWindow.y, 0.3, 0.3); - phillyWindowEvent.setGraphicSize(Std.int(phillyWindowEvent.width * 0.85)); - phillyWindowEvent.updateHitbox(); - phillyWindowEvent.visible = false; - insert(members.indexOf(blammedLightsBlack) + 1, phillyWindowEvent); - - - phillyGlowGradient = new PhillyGlow.PhillyGlowGradient(-400, 225); //This shit was refusing to properly load FlxGradient so fuck it - phillyGlowGradient.visible = false; - insert(members.indexOf(blammedLightsBlack) + 1, phillyGlowGradient); - if(!ClientPrefs.flashing) phillyGlowGradient.intendedAlpha = 0.7; - - precacheList.set('philly/particle', 'image'); //precache particle image - phillyGlowParticles = new FlxTypedGroup(); - phillyGlowParticles.visible = false; - insert(members.indexOf(phillyGlowGradient) + 1, phillyGlowParticles); - } - - if(!eventPushedMap.exists(event.event) && SONG.song.toLowerCase() != 'anti-cheat-song') { - eventPushedMap.set(event.event, true); - } - } - - function eventNoteEarlyTrigger(event:EventNote):Float { - var returnedValue:Null = callOnLuas('eventEarlyTrigger', [event.event, event.value1, event.value2, event.strumTime], [], [0]); - if(returnedValue != null && returnedValue != 0 && returnedValue != FunkinLua.Function_Continue) { - return returnedValue; - } - - switch(event.event) { - case 'Kill Henchmen': //Better timing so that the kill sound matches the beat intended - return 280; //Plays 280ms before the actual position - } - return 0; - } - - function sortByTime(Obj1:Dynamic, Obj2:Dynamic):Int - { - return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime); - } - - function sortByShit(Obj1:Note, Obj2:Note):Int { - return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime); - } - - public var skipArrowStartTween:Bool = false; //for lua - private function generateStaticArrows(player:Int):Void - { - for (i in 0...4) - { - // FlxG.log.add(i); - var targetAlpha:Float = 1; - if (player < 1) - { - if(!ClientPrefs.opponentStrums) targetAlpha = 0; - else if(ClientPrefs.middleScroll || ClientPrefs.mobileMidScroll) targetAlpha = ClientPrefs.oppNoteAlpha; - if (ClientPrefs.mobileMidScroll) opponentStrums.members[i].x == FlxG.width - 2; //make it so that you're unable to see the opponent's strums if you have mobile styled middlescroll on - } - - var babyArrow:StrumNote = new StrumNote(ClientPrefs.middleScroll || ClientPrefs.mobileMidScroll ? STRUM_X_MIDDLESCROLL : STRUM_X, strumLine.y, i, player); - babyArrow.downScroll = ClientPrefs.downScroll; - if (!isStoryMode && !skipArrowStartTween) - { - //babyArrow.y -= 10; - babyArrow.alpha = 0; - FlxTween.tween(babyArrow, {/*y: babyArrow.y + 10,*/ alpha: targetAlpha}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * i)}); - } - else - { - babyArrow.alpha = targetAlpha; - } - - if (player == 1) - { - if (!opponentChart || opponentChart && ClientPrefs.middleScroll || opponentChart && ClientPrefs.mobileMidScroll || !opponentChart && ClientPrefs.mobileMidScroll) playerStrums.add(babyArrow); - else if (ClientPrefs.mobileMidScroll) insert(members.indexOf(playerStrums), babyArrow); - else opponentStrums.add(babyArrow); - } - else - { - if(ClientPrefs.middleScroll) - { - babyArrow.x += 310; - if(i > 1) { //Up and Right - babyArrow.x += FlxG.width / 2 + 25; - } - } - if(ClientPrefs.mobileMidScroll) - { - babyArrow.x += FlxG.width / 2; - } - if (!opponentChart || opponentChart && ClientPrefs.mobileMidScroll || opponentChart && ClientPrefs.mobileMidScroll || !opponentChart && ClientPrefs.mobileMidScroll) opponentStrums.add(babyArrow); - else if (ClientPrefs.mobileMidScroll) insert(members.indexOf(playerStrums), babyArrow); - else playerStrums.add(babyArrow); - } - - strumLineNotes.add(babyArrow); - babyArrow.postAddedToGroup(); - } - } - - override function openSubState(SubState:FlxSubState) - { - if (paused) - { - if (FlxG.sound.music != null) - { - if (ClientPrefs.songLoading) { - FlxG.sound.music.pause(); - vocals.pause(); - } - } - - if (startTimer != null && !startTimer.finished) - startTimer.active = false; - if (finishTimer != null && !finishTimer.finished) - finishTimer.active = false; - if (songSpeedTween != null) - songSpeedTween.active = false; - - if(carTimer != null) carTimer.active = false; - - var chars:Array = [boyfriend, gf, dad]; - for (char in chars) { - if(char != null && char.colorTween != null) { - char.colorTween.active = false; - } - } - - for (tween in modchartTweens) { - tween.active = false; - } - for (timer in modchartTimers) { - timer.active = false; - } - } - - super.openSubState(SubState); - } - - override function closeSubState() - { - if (paused) - { - if (FlxG.sound.music != null && !startingSong && !ClientPrefs.noSyncing) - { - resyncVocals(); - } - - if (startTimer != null && !startTimer.finished) - startTimer.active = true; - if (finishTimer != null && !finishTimer.finished) - finishTimer.active = true; - if (songSpeedTween != null) - songSpeedTween.active = true; - - if(carTimer != null) carTimer.active = true; - - var chars:Array = [boyfriend, gf, dad]; - for (char in chars) { - if(char != null && char.colorTween != null) { - char.colorTween.active = true; - } - } - - for (tween in modchartTweens) { - tween.active = true; - } - for (timer in modchartTimers) { - timer.active = true; - } - paused = false; - callOnLuas('onResume', []); - - #if desktop - if (startTimer != null && startTimer.finished) - { - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter(), true, songLength - Conductor.songPosition - ClientPrefs.noteOffset); - } - else - { - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); - } - #end - } - - super.closeSubState(); - } - - override public function onFocus():Void - { - #if desktop - if (health > 0 && !paused) - { - if (Conductor.songPosition > 0.0) - { - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter(), true, songLength - Conductor.songPosition - ClientPrefs.noteOffset); - } - else - { - DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); - } - } - #end - - super.onFocus(); - } - - override public function onFocusLost():Void - { - #if desktop - if (health > 0 && !paused) - { - DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); - } - #end - - super.onFocusLost(); - } - - function resyncVocals():Void - { - if(finishTimer != null) return; - - FlxG.sound.music.pitch = playbackRate; - vocals.pitch = playbackRate; - if (ClientPrefs.resyncType == 'Leather') - { - if(!(Conductor.songPosition > 20 && FlxG.sound.music.time < 20)) - { - //trace("SONG POS: " + Conductor.songPosition + " | Musice: " + FlxG.sound.music.time + " / " + FlxG.sound.music.length); - - vocals.pause(); - FlxG.sound.music.pause(); - - if(FlxG.sound.music.time >= FlxG.sound.music.length) - Conductor.songPosition = FlxG.sound.music.length; - else - Conductor.songPosition = FlxG.sound.music.time; - - vocals.time = Conductor.songPosition; - - FlxG.sound.music.play(); - vocals.play(); - } - else - { - while(Conductor.songPosition > 20 && FlxG.sound.music.time < 20) - { - trace("SONG POS: " + Conductor.songPosition + " | Music Pos: " + FlxG.sound.music.time + " / " + FlxG.sound.music.length); - - FlxG.sound.music.time = Conductor.songPosition; - vocals.time = Conductor.songPosition; - - FlxG.sound.music.play(); - vocals.play(); - } - } - } - else if (ClientPrefs.resyncType == 'Psych') - { - vocals.pause(); - FlxG.sound.music.play(); - - Conductor.songPosition = FlxG.sound.music.time; - if (Conductor.songPosition <= vocals.length) - { - vocals.time = Conductor.songPosition; - } - vocals.play(); - } - } - - public var paused:Bool = false; - public var canReset:Bool = true; - var startedCountdown:Bool = false; - var canPause:Bool = true; - var limoSpeed:Float = 0; - var pbRM:Float = 2.0; - override public function update(elapsed:Float) - { - if (health <= 0 && practiceMode && ClientPrefs.zeroHealthLimit) - { - health = 0; //set health to 0 if on practice mode and you get to 0% - } - if (combo >= 1.79e+308) combo = 1.79e+308; //Combo exceeded the maximum value that a Float can go up to, lock it at 1.79e+308 to avoid a reset to 0 - if (totalNotesPlayed >= 1.79e+308) totalNotesPlayed = 1.79e+308; //Note hit count exceeded the maximum value that a Float can go up to, lock it at 1.79e+308 to avoid a reset to 0 - if (enemyHits >= 1.79e+308) enemyHits = 1.79e+308; //Opponent's note hit count exceeded the maximum value that a Float can go up to, lock it at 1.79e+308 to avoid a reset to 0 - if (FlxG.sound.music.length - Conductor.songPosition <= 1000 && ClientPrefs.communityGameBot && cpuControlled) { - ratingName = 'you used the community game bot option LMFAOOO'; - ratingFC = 'skill issue'; - } - if (ClientPrefs.comboScoreEffect && ClientPrefs.comboMultiType == 'osu!') comboMultiplier = 1 + FlxMath.roundDecimal((combo / 100), 2); - if (ClientPrefs.comboScoreEffect && comboMultiplier > ClientPrefs.comboMultLimit) comboMultiplier = ClientPrefs.comboMultLimit; - /*if (FlxG.keys.justPressed.NINE) - { - iconP1.swapOldIcon(); - }*/ - if (ClientPrefs.pbRControls) - { - if (FlxG.keys.pressed.SHIFT) { - pbRM = 4.0; - } else { - pbRM = 2.0; - } - if (FlxG.keys.justPressed.SLASH) { - playbackRate /= pbRM; - } - if (FlxG.keys.justPressed.PERIOD) { - playbackRate *= pbRM; - } - } - healthBar.setRange(0, maxHealth); - - callOnLuas('onUpdate', [elapsed]); - - playbackRateDecimal = FlxMath.roundDecimal(playbackRate, 2); - - if (goods > 0 || bads > 0 || shits > 0 || songMisses > 0 && sickOnly) - { - // if it isn't a sick, and sick only mode is on YOU DIE - if (sickOnly) - { - health = -2; - } - } - - if (tankmanAscend) - { - if (curStep > 895 && curStep < 1151) - { - camGame.zoom = 0.8; - } - } - - switch (curStage) - { - case 'tank': - moveTank(elapsed); - case 'schoolEvil': - if(!ClientPrefs.lowQuality && bgGhouls.animation.curAnim.finished) { - bgGhouls.visible = false; - } - case 'philly': - if (trainMoving) - { - trainFrameTiming += elapsed; - - if (trainFrameTiming >= 1 / 24) - { - updateTrainPos(); - trainFrameTiming = 0; - } - } - phillyWindow.alpha -= (Conductor.crochet / 1000) * FlxG.elapsed * 1.5; - - if(phillyGlowParticles != null) - { - var i:Int = phillyGlowParticles.members.length-1; - while (i > 0) - { - var particle = phillyGlowParticles.members[i]; - if(particle.alpha < 0) - { - particle.kill(); - phillyGlowParticles.remove(particle, true); - particle.destroy(); - } - --i; - } - } - case 'limo': - if(!ClientPrefs.lowQuality) { - grpLimoParticles.forEach(function(spr:BGSprite) { - if(spr.animation.curAnim.finished) { - spr.kill(); - grpLimoParticles.remove(spr, true); - spr.destroy(); - } - }); - - switch(limoKillingState) { - case 1: - limoMetalPole.x += 5000 * elapsed; - limoLight.x = limoMetalPole.x - 180; - limoCorpse.x = limoLight.x - 50; - limoCorpseTwo.x = limoLight.x + 35; - - var dancers:Array = grpLimoDancers.members; - for (i in 0...dancers.length) { - if(dancers[i].x < FlxG.width * 1.5 && limoLight.x > (370 * i) + 170) { - switch(i) { - case 0 | 3: - if(i == 0) FlxG.sound.play(Paths.sound('dancerdeath'), 0.5); - - var diffStr:String = i == 3 ? ' 2 ' : ' '; - var particle:BGSprite = new BGSprite('gore/noooooo', dancers[i].x + 200, dancers[i].y, 0.4, 0.4, ['hench leg spin' + diffStr + 'PINK'], false); - grpLimoParticles.add(particle); - var particle:BGSprite = new BGSprite('gore/noooooo', dancers[i].x + 160, dancers[i].y + 200, 0.4, 0.4, ['hench arm spin' + diffStr + 'PINK'], false); - grpLimoParticles.add(particle); - var particle:BGSprite = new BGSprite('gore/noooooo', dancers[i].x, dancers[i].y + 50, 0.4, 0.4, ['hench head spin' + diffStr + 'PINK'], false); - grpLimoParticles.add(particle); - - var particle:BGSprite = new BGSprite('gore/stupidBlood', dancers[i].x - 110, dancers[i].y + 20, 0.4, 0.4, ['blood'], false); - particle.flipX = true; - particle.angle = -57.5; - grpLimoParticles.add(particle); - case 1: - limoCorpse.visible = true; - case 2: - limoCorpseTwo.visible = true; - } //Note: Nobody cares about the fifth dancer because he is mostly hidden offscreen :( - dancers[i].x += FlxG.width * 2; - } - } - - if(limoMetalPole.x > FlxG.width * 2) { - resetLimoKill(); - limoSpeed = 800; - limoKillingState = 2; - } - - case 2: - limoSpeed -= 4000 * elapsed; - bgLimo.x -= limoSpeed * elapsed; - if(bgLimo.x > FlxG.width * 1.5) { - limoSpeed = 3000; - limoKillingState = 3; - } - - case 3: - limoSpeed -= 2000 * elapsed; - if(limoSpeed < 1000) limoSpeed = 1000; - - bgLimo.x -= limoSpeed * elapsed; - if(bgLimo.x < -275) { - limoKillingState = 4; - limoSpeed = 800; - } - - case 4: - bgLimo.x = FlxMath.lerp(bgLimo.x, -150, CoolUtil.boundTo(elapsed * 9, 0, 1)); - if(Math.round(bgLimo.x) == -150) { - bgLimo.x = -150; - limoKillingState = 0; - } - } - - if(limoKillingState > 2) { - var dancers:Array = grpLimoDancers.members; - for (i in 0...dancers.length) { - dancers[i].x = (370 * i) + bgLimo.x + 280; - } - } - } - case 'mall': - if(heyTimer > 0) { - heyTimer -= elapsed; - if(heyTimer <= 0) { - bottomBoppers.dance(true); - heyTimer = 0; - } - } - } - - if(!inCutscene) { - var lerpVal:Float = CoolUtil.boundTo(elapsed * 2.4 * cameraSpeed * playbackRate, 0, 1); - camFollowPos.setPosition(FlxMath.lerp(camFollowPos.x + moveCamTo[0]/102, camFollow.x + moveCamTo[0]/102, lerpVal), FlxMath.lerp(camFollowPos.y + moveCamTo[1]/102, camFollow.y + moveCamTo[1]/102, lerpVal)); - if (ClientPrefs.charsAndBG) { - if(!startingSong && !endingSong && boyfriend.animation.curAnim != null && boyfriend.animation.curAnim.name.startsWith('idle')) { - boyfriendIdleTime += elapsed; - if(boyfriendIdleTime >= 0.15) { // Kind of a mercy thing for making the achievement easier to get as it's apparently frustrating to some playerss - boyfriendIdled = true; - } - } else { - boyfriendIdleTime = 0; - } - } - var panLerpVal:Float = CoolUtil.clamp(elapsed * 4.4 * cameraSpeed, 0, 1); - moveCamTo[0] = FlxMath.lerp(moveCamTo[0], 0, panLerpVal); - moveCamTo[1] = FlxMath.lerp(moveCamTo[1], 0, panLerpVal); - } - - if (ClientPrefs.hudType == 'Leather Engine' && SONG.notes[curSection] != null) timeBar.color = SONG.notes[curSection].mustHitSection ? FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2]) : FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]); -if (ClientPrefs.showNPS) { - var currentTime = Date.now().getTime(); - var timeThreshold = ClientPrefs.npsWithSpeed ? 1000 / playbackRate : 1000; - - // Track the count of items to remove for notesHitDateArray - var notesToRemoveCount:Int = 0; - - // Filter notesHitDateArray and notesHitArray in place - for (i in 0...notesHitDateArray.length) { - var cock:Date = notesHitDateArray[i]; - if (cock != null && (cock.getTime() + timeThreshold < currentTime)) { - notesToRemoveCount++; - } - } - - // Remove items from notesHitDateArray and notesHitArray if needed - if (notesToRemoveCount > 0) { - notesHitDateArray.splice(0, notesToRemoveCount); - notesHitArray.splice(0, notesToRemoveCount); - if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0 && judgementCounter != null) updateRatingCounter(); - if (!ClientPrefs.hideScore && scoreTxtUpdateFrame == 0 && scoreTxt != null) updateScore(); - if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); - } - - // Calculate sum of NPS values - var sum:Float = 0.0; - for (value in notesHitArray) { - sum += value; - } - nps = sum; - - // Similar tracking and filtering logic for oppNotesHitDateArray - var oppNotesToRemoveCount:Int = 0; - - for (i in 0...oppNotesHitDateArray.length) { - var cock:Date = oppNotesHitDateArray[i]; - if (cock != null && (cock.getTime() + timeThreshold < currentTime)) { - oppNotesToRemoveCount++; - } - } - - // Remove items from oppNotesHitDateArray and oppNotesHitArray if needed - if (oppNotesToRemoveCount > 0) { - oppNotesHitDateArray.splice(0, oppNotesToRemoveCount); - oppNotesHitArray.splice(0, oppNotesToRemoveCount); - if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0 && judgementCounter != null) updateRatingCounter(); - if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); - } - - // Calculate sum of NPS values for the opponent - var oppSum:Float = 0.0; - for (value in oppNotesHitArray) { - oppSum += value; - } - oppNPS = oppSum; - - // Update maxNPS and maxOppNPS if needed - if (oppNPS > maxOppNPS) { - maxOppNPS = oppNPS; - } - if (nps > maxNPS) { - maxNPS = nps; - } -} - - if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) { - hitTxt.text = 'Notes Hit: ' + FlxStringUtil.formatMoney(totalNotesPlayed, false) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) - + '\nNPS (Max): ' + FlxStringUtil.formatMoney(nps, false) + ' (' + FlxStringUtil.formatMoney(maxNPS, false) + ')' - + '\nOpponent Notes Hit: ' + FlxStringUtil.formatMoney(enemyHits, false) - + '\nOpponent NPS (Max): ' + FlxStringUtil.formatMoney(oppNPS, false) + ' (' + FlxStringUtil.formatMoney(maxOppNPS, false) + ')' - + '\nTotal Note Hits: ' + FlxStringUtil.formatMoney(Math.abs(totalNotesPlayed + enemyHits), false) - + '\nVideo Speedup: ' + Math.abs(playbackRate / playbackRate / playbackRate) + 'x'; - } - if (notesHitArray.length == 1 || oppNotesHitArray.length == 1) { - if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0 && judgementCounter != null) updateRatingCounter(); - if (!ClientPrefs.hideScore && scoreTxtUpdateFrame == 0 && scoreTxt != null) updateScore(); - if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); - } - - if (combo > maxCombo) - maxCombo = combo; - - super.update(elapsed); - judgeCountUpdateFrame = 0; - compactUpdateFrame = 0; - scoreTxtUpdateFrame = 0; - - if (shownScore != songScore && ClientPrefs.hudType == 'JS Engine' && Math.abs(shownScore - songScore) >= 10) { - shownScore = FlxMath.lerp(shownScore, songScore, 0.4 / (ClientPrefs.framerate / 60)); - lerpingScore = true; // Indicate that lerping is in progress - } else { - shownScore = songScore; - lerpingScore = false; - } - - if (lerpingScore) updateScore(); - - if (ClientPrefs.smoothHealth && ClientPrefs.smoothHealthType == 'Indie Cross') - { - if (ClientPrefs.framerate > 60) - { - displayedHealth = FlxMath.lerp(displayedHealth, health, .1); - } else if (ClientPrefs.framerate == 60) - { - displayedHealth = FlxMath.lerp(displayedHealth, health, .4); - } - } - if (ClientPrefs.smoothHealth && ClientPrefs.smoothHealthType == 'Golden Apple 1.5') - { - displayedHealth = FlxMath.lerp(displayedHealth, health, CoolUtil.boundTo(elapsed * 20, 0, 1)); - } - if (!ClientPrefs.smoothHealth) //so basically don't make the health smooth if you have that off - { - displayedHealth = health; - } - - setOnLuas('curDecStep', curDecStep); - setOnLuas('curDecBeat', curDecBeat); - - if(botplayTxt != null && ClientPrefs.hudType != "Mic'd Up" && ClientPrefs.hudType != 'Kade Engine' && ClientPrefs.botTxtFade) { - botplaySine += 180 * elapsed; - botplayTxt.alpha = 1 - Math.sin((Math.PI * botplaySine) / 180 * playbackRate); - } - if((botplayTxt != null && cpuControlled && !ClientPrefs.showcaseMode) && ClientPrefs.randomBotplayText && !ClientPrefs.communityGameBot) { - if(botplayTxt.text == "this text is gonna kick you out of botplay in 10 seconds" && !botplayUsed || botplayTxt.text == "Your Botplay Free Trial will end in 10 seconds." && !botplayUsed) - { - botplayUsed = true; - new FlxTimer().start(10, function(tmr:FlxTimer) - { - cpuControlled = false; - botplayUsed = false; - botplayTxt.visible = false; - }); - } - if(botplayTxt.text == "You use botplay? In 10 seconds I knock your botplay thing and text so you'll never use it >:)" && !botplayUsed) - { - botplayUsed = true; - new FlxTimer().start(10, function(tmr:FlxTimer) - { - cpuControlled = false; - botplayUsed = false; - FlxG.sound.play(Paths.sound('pipe'), 10); - botplayTxt.visible = false; - PauseSubState.botplayLockout = true; - }); - } - if(botplayTxt.text == "you have 10 seconds to run." && !botplayUsed) - { - botplayUsed = true; - new FlxTimer().start(10, function(tmr:FlxTimer) - { - var vidSpr:FlxSprite; - var videoDone:Bool = true; - var video:MP4Handler = new MP4Handler(); // it plays but it doesn't show??? - vidSpr = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.WHITE); - add(vidSpr); - #if (hxCodec < "3.0.0") - video.playVideo(Paths.video('scary'), false, false); - video.finishCallback = function() - { - videoDone = true; - vidSpr.visible = false; - Sys.exit(0); - }; - #else - video.play(Paths.video('scary')); - video.onEndReached.add(function(){ - video.dispose(); - videoDone = true; - vidSpr.visible = false; - Sys.exit(0); - }); - #end - }); - } - if(botplayTxt.text == "you're about to die in 30 seconds" && !botplayUsed) - { - botplayUsed = true; - new FlxTimer().start(30, function(tmr:FlxTimer) - { - health = 0; - }); - } - if(botplayTxt.text == "3 minutes until Boyfriend steals your liver." && !botplayUsed) - { - var title:String = 'Incoming Alert from Boyfriend'; - var message:String = '3 minutes until Boyfriend steals your liver!'; - FlxG.sound.music.pause(); - vocals.pause(); - - lime.app.Application.current.window.alert(message, title); - FlxG.sound.music.resume(); - vocals.resume(); - botplayUsed = true; - new FlxTimer().start(180, function(tmr:FlxTimer) - { - Sys.exit(0); - }); - } - if(botplayTxt.text == "3 minutes until I steal your liver." && !botplayUsed) - { - var title:String = 'Incoming Alert from Jordan'; - var message:String = '3 minutes until I steal your liver.'; - FlxG.sound.music.pause(); - vocals.pause(); - - lime.app.Application.current.window.alert(message, title); - FlxG.sound.music.resume(); - vocals.resume(); - botplayUsed = true; - new FlxTimer().start(180, function(tmr:FlxTimer) - { - Sys.exit(0); - }); - } - } - - if ((controls.PAUSE #if android || FlxG.android.justReleased.BACK #end) && startedCountdown && canPause && !softlocked) - { - if (!ClientPrefs.noPausing) { - var ret:Dynamic = callOnLuas('onPause', [], false); - if(ret != FunkinLua.Function_Stop) { - openPauseMenu(); - } - } - else if (ClientPrefs.noPausing) { - FlxTween.cancelTweensOf(pauseWarnText); - trace("Player has attempted to pause the song, but 'Force Disable Pausing' is enabled! (Tries: " + tries + ")"); - pauseWarnText.visible = true; - pauseWarnText.alpha = 1; - FlxG.sound.play(Paths.sound('tried'), 1); - tries++; - insert(members.indexOf(strumLineNotes), pauseWarnText); - FlxTween.tween(pauseWarnText, {alpha: 0}, 1 / playbackRate, { - startDelay: 2 / playbackRate, - onComplete: _ -> { - tries = 0; - pauseWarnText.visible = false; - } - }); - switch (tries) - { - case 1, 2, 3, 4, 5, 6, 7, 8, 9: - pauseWarnText.text = "Pausing is disabled! Turn it back on in Settings -> Gameplay -> 'Force Disable Pausing'"; - case 10, 11, 12, 13, 14, 15, 16, 17, 18, 19: - pauseWarnText.text = "OK we get it, the sound's funny, now stop pausing."; - case 20, 21, 22, 23, 24, 25, 26, 27, 28, 29: - pauseWarnText.text = "dude. stop."; - case 30, 31, 32, 33, 34: - pauseWarnText.text = "OK, if you continue, I'm softlocking the game."; - case 35, 36, 37, 38, 39: - pauseWarnText.text = "STOP."; - case 40: - pauseWarnText.text = "fuck off."; - FlxG.sound.play(Paths.sound('pipe'), 1); - if (ClientPrefs.songLoading) vocals.stop(); - if (ClientPrefs.songLoading) FlxG.sound.music.stop(); - Conductor.songPosition = -10000000000; - restartTimer = new FlxTimer().start(10, function(_) { - PauseSubState.restartSong(true); - }); - case 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59: - pauseWarnText.text = "stop trying to pause dumbass this is getting you nowhere"; - case 60: - pauseWarnText.text = "I CAN PERMANENTLY PAUSE FOR YOU, IF THAT'S WHAT YOU WANT."; - case 80: - pauseWarnText.text = "STOP. PAUSING."; - case 90: - pauseWarnText.text = "IM WARNING YOU, STOP PAUSING."; - case 95: - pauseWarnText.text = "I WILL NOT HESITATE TO SOFTLOCK THIS GAME RIGHT NOW."; - case 99: - pauseWarnText.text = "pause one more fucking time i FUCKING DARE YOU."; - case 100: - pauseWarnText.text = "ok fine you stupid fuck ive paused your fucking game, are you happy now"; - FlxG.sound.play(Paths.sound('loudvine'), 1); - if (restartTimer != null) restartTimer.cancel(); - softlocked = true; - trace("softlocked the game lmao"); - } - } - } - - if (FlxG.keys.anyJustPressed(debugKeysChart) && !endingSong && !inCutscene && !softlocked) - { - if (!ClientPrefs.antiCheatEnable) - { - openChartEditor(); - } - if (ClientPrefs.antiCheatEnable) - { - PlayState.SONG = Song.loadFromJson('Anti-cheat-song', 'Anti-cheat-song'); - LoadingState.loadAndSwitchState(new PlayState()); - } - } - - // FlxG.watch.addQuick('VOL', vocals.amplitudeLeft); - // FlxG.watch.addQuick('VOLRight', vocals.amplitudeRight); - - if (ClientPrefs.iconBounceType == 'Old Psych') { - iconP1.setGraphicSize(Std.int(FlxMath.lerp(150, iconP1.width, CoolUtil.boundTo(1 - (elapsed * 30 * playbackRate), 0, 1)))); - iconP2.setGraphicSize(Std.int(FlxMath.lerp(150, iconP2.width, CoolUtil.boundTo(1 - (elapsed * 30 * playbackRate), 0, 1)))); - } - if (ClientPrefs.iconBounceType == 'Strident Crisis') { - iconP1.setGraphicSize(Std.int(FlxMath.lerp(150, iconP1.width, 0.50 / playbackRate))); - iconP1.updateHitbox(); - - iconP2.setGraphicSize(Std.int(FlxMath.lerp(150, iconP2.width, 0.50 / playbackRate))); - iconP2.updateHitbox(); - } - if (ClientPrefs.iconBounceType == 'Dave and Bambi') { - iconP1.setGraphicSize(Std.int(FlxMath.lerp(150, iconP1.width, 0.8 / playbackRate)),Std.int(FlxMath.lerp(150, iconP1.height, 0.8 / playbackRate))); - iconP2.setGraphicSize(Std.int(FlxMath.lerp(150, iconP2.width, 0.8 / playbackRate)),Std.int(FlxMath.lerp(150, iconP2.height, 0.8 / playbackRate))); - } - if (ClientPrefs.iconBounceType == 'Plank Engine') { - var funnyBeat = (Conductor.songPosition / 1000) * (Conductor.bpm / 60); - - iconP1.offset.y = Math.abs(Math.sin(funnyBeat * Math.PI)) * 16 - 4; - iconP2.offset.y = Math.abs(Math.sin(funnyBeat * Math.PI)) * 16 - 4; - } - if (ClientPrefs.iconBounceType == 'New Psych') { - var mult:Float = FlxMath.lerp(1, iconP1.scale.x, CoolUtil.boundTo(1 - (elapsed * 9 * playbackRate), 0, 1)); - iconP1.scale.set(mult, mult); - iconP1.updateHitbox(); - - var mult:Float = FlxMath.lerp(1, iconP2.scale.x, CoolUtil.boundTo(1 - (elapsed * 9 * playbackRate), 0, 1)); - iconP2.scale.set(mult, mult); - iconP2.updateHitbox(); - } - if (ClientPrefs.iconBounceType == 'VS Steve') { - var mult:Float = FlxMath.lerp(1, iconP1.scale.x, CoolUtil.boundTo(1 - (elapsed * 9 * playbackRate), 0, 1)); - iconP1.scale.set(mult, mult); - iconP1.updateHitbox(); - - var mult:Float = FlxMath.lerp(1, iconP2.scale.x, CoolUtil.boundTo(1 - (elapsed * 9 * playbackRate), 0, 1)); - iconP2.scale.set(mult, mult); - iconP2.updateHitbox(); - } - - if (ClientPrefs.iconBounceType == 'Golden Apple') { - iconP1.centerOffsets(); - iconP2.centerOffsets(); - } - iconP1.updateHitbox(); - iconP2.updateHitbox(); - - var iconOffset:Int = 26; - - if (ClientPrefs.smoothHealth && ClientPrefs.smoothHealthType != 'Golden Apple 1.5' || !ClientPrefs.smoothHealth) //checks if you're using smooth health. if you are, but are not using the indie cross one then you know what that means - { - iconP1.x = (opponentChart ? -593 : 0) + healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, (opponentChart ? -100 : 100), 100, 0) * 0.01)) + (150 * iconP1.scale.x - 150) / 2 - iconOffset; - iconP2.x = (opponentChart ? -593 : 0) + healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, (opponentChart ? -100 : 100), 100, 0) * 0.01)) - (150 * iconP2.scale.x) / 2 - iconOffset * 2; - } - if (ClientPrefs.smoothHealth && ClientPrefs.smoothHealthType == 'Golden Apple 1.5') //really makes it feel like the gapple 1.5 build's health tween - { - var percent:Float = 1 - (opponentChart ? displayedHealth / maxHealth * -1 : displayedHealth / maxHealth); //checks if you're playing as the opponent. if so, uses the negative percent, otherwise uses the normal one - iconP1.x = (opponentChart ? -593 : 0) + healthBar.x + (healthBar.width * percent) + (150 * iconP1.scale.x - 150) / 2 - iconOffset; - iconP2.x = (opponentChart ? -593 : 0) + healthBar.x + (healthBar.width * percent) - (150 * iconP2.scale.x) / 2 - iconOffset * 2; - } - - if (generatedMusic) { - if (startedCountdown && canPause && !endingSong) { - if (playbackRate <= 256) endingTimeLimit = 20; - // Song ends abruptly on slow rate even with second condition being deleted, - // and if it's deleted on songs like cocoa then it would end without finishing instrumental fully, - // so no reason to delete it at all - if (ClientPrefs.songLoading && FlxG.sound.music.length - Conductor.songPosition <= endingTimeLimit && trollingMode) { //stop crashes when playing normally - if (ClientPrefs.trollMaxSpeed == 'Highest') loopSongHighest(); - if (ClientPrefs.trollMaxSpeed == 'High') loopSongHigh(); - if (ClientPrefs.trollMaxSpeed == 'Medium') loopSongMedium(); - if (ClientPrefs.trollMaxSpeed == 'Low') loopSongLow(); - if (ClientPrefs.trollMaxSpeed == 'Lower') loopSongLower(); - if (ClientPrefs.trollMaxSpeed == 'Lowest') loopSongLowest(); - if (ClientPrefs.trollMaxSpeed == 'Disabled') loopSongNoLimit(); - FlxG.sound.music.time = 0; - vocals.time = 0; - Conductor.songPosition = 0; - curSection = 0; - curBeat = 0; - curStep = 0; - } - if (ClientPrefs.songLoading && FlxG.sound.music.length - Conductor.songPosition <= endingTimeLimit && SONG.song.toLowerCase() == 'anti-cheat-song') { //stop crashes when playing normally - infiniteLoop(); - FlxG.sound.music.time = 0; - vocals.time = 0; - Conductor.songPosition = 0; - curSection = 0; - curBeat = 0; - curStep = 0; - } - } - } - - if (28820000 - Conductor.songPosition <= 20 && SONG.song.toLowerCase() == 'desert bus') { //stop crashes when playing normally - endSong(); - } - - if (health > maxHealth) - health = maxHealth; - - // this was giving me a headache rewriting this :D - var stupidIcons:Array = [iconP1, iconP2]; - if (opponentChart) stupidIcons = [iconP2, iconP1]; - - if (healthBar.percent < 20){ - stupidIcons[0].animation.curAnim.curFrame = 1; - if (stupidIcons[1].width == 450) - stupidIcons[1].animation.curAnim.curFrame = 2; - } - else if (healthBar.percent > 80){ - if (stupidIcons[0].width == 450) - stupidIcons[0].animation.curAnim.curFrame = 2; - stupidIcons[1].animation.curAnim.curFrame = 1; - } - else{ - stupidIcons[0].animation.curAnim.curFrame = 0; - stupidIcons[1].animation.curAnim.curFrame = 0; - } - - if (FlxG.keys.anyJustPressed(debugKeysCharacter) && !endingSong && !inCutscene && !softlocked) { - persistentUpdate = false; - paused = true; - cancelMusicFadeTween(); - MusicBeatState.switchState(new CharacterEditorState(SONG.player2)); - } - - if (startedCountdown) - { - Conductor.songPosition += FlxG.elapsed * 1000 * playbackRate; - } - - if (startingSong) - { - if (startedCountdown && Conductor.songPosition >= 0) - startSong(); - else if(!startedCountdown) - Conductor.songPosition = -Conductor.crochet * 5; - } - else - { - if (!paused) - { - songTime += FlxG.game.ticks - previousFrameTime; - previousFrameTime = FlxG.game.ticks; - //Interpolation type beat - if (Conductor.lastSongPos != Conductor.songPosition && ClientPrefs.songLoading) - { - songTime = (songTime + Conductor.songPosition) / 2; - Conductor.lastSongPos = Conductor.songPosition; - // Conductor.songPosition += FlxG.elapsed * 1000; - // trace('MISSED FRAME'); - } - - if(updateTime) { - var curTime:Float = Conductor.songPosition - ClientPrefs.noteOffset; - if(curTime < 0) curTime = 0; - songPercent = (curTime / songLength); - var songDurationSeconds:Float = FlxMath.roundDecimal(songLength / 1000, 0); - songPercentThing = FlxMath.roundDecimal(curTime / songLength * 100, ClientPrefs.percentDecimals); - playbackRateDecimal = FlxMath.roundDecimal(playbackRate, 2); - - var songCalc:Float = (songLength - curTime); - if(ClientPrefs.timeBarType == 'Time Elapsed' || ClientPrefs.timeBarType == 'Modern Time' || ClientPrefs.timeBarType == 'Song Name + Time') songCalc = curTime; - - var secondsTotal:Int = 0; - - secondsTotal = Math.floor(songCalc / 1000); - if(secondsTotal < 0) secondsTotal = 0; - if(trollingMode && ClientPrefs.songLoading && Conductor.songPosition - FlxG.sound.music.length == endingTimeLimit) secondsTotal == secondsTotal + FlxG.sound.music.length; - - - var hoursRemaining:Int = Math.floor(secondsTotal / 3600); - var minutesRemaining:Int = Math.floor(secondsTotal / 60) % 60; - var minutesRemainingShit:String = '' + minutesRemaining; - var secondsRemaining:String = '' + secondsTotal % 60; - - if(secondsRemaining.length < 2) secondsRemaining = '0' + secondsRemaining; //let's see if the old time format works actually - //if (minutesRemaining == 60) minutesRemaining = 0; //reset the minutes to 0 every time it counts another hour - if (minutesRemainingShit.length < 2) minutesRemainingShit = '0' + minutesRemaining; - //also, i wont add a day thing because there's no way someone can mod a song that's over 24 hours long into this engine - - var hoursShown:Int = Math.floor(songDurationSeconds / 3600); - var minutesShown:Int = Math.floor(songDurationSeconds / 60) % 60; - var minutesShownShit:String = '' + minutesShown; - var secondsShown:String = '' + songDurationSeconds % 60; - if(secondsShown.length < 2) secondsShown = '0' + secondsShown; //let's see if the old time format works actually - if (minutesShownShit.length < 2) minutesShownShit = '0' + minutesShown; - - - if(ClientPrefs.timeBarType != 'Song Name' && songLength <= 3600000) - timeTxt.text = FlxStringUtil.formatTime(secondsTotal, false); - - if(ClientPrefs.timeBarType != 'Song Name' && songLength >= 3600000) - timeTxt.text = hoursRemaining + ':' + minutesRemainingShit + ':' + secondsRemaining; - - if(ClientPrefs.timeBarType == 'Modern Time' && songLength <= 3600000) - timeTxt.text = FlxStringUtil.formatTime(secondsTotal, false) + ' / ' + FlxStringUtil.formatTime(songLength / 1000, false); - - if(ClientPrefs.timeBarType == 'Modern Time' && songLength >= 3600000) - timeTxt.text = hoursRemaining + ':' + minutesRemainingShit + ':' + secondsRemaining + ' / ' + hoursShown + ':' + minutesShownShit + ':' + secondsShown; - - if(ClientPrefs.timeBarType == 'Song Name + Time' && songLength <= 3600000) - timeTxt.text = SONG.song + ' (' + FlxStringUtil.formatTime(secondsTotal, false) + ' / ' + FlxStringUtil.formatTime(songLength / 1000, false) + ')'; - - if(ClientPrefs.timeBarType == 'Song Name + Time' && songLength >= 3600000) - timeTxt.text = SONG.song + ' (' + hoursRemaining + ':' + minutesRemainingShit + ':' + secondsRemaining + ' / ' + hoursShown + ':' + minutesShownShit + ':' + secondsShown + ')'; - - if(ClientPrefs.timebarShowSpeed && ClientPrefs.timeBarType != 'Song Name') timeTxt.text += ' (' + playbackRateDecimal + 'x)'; - if(ClientPrefs.timebarShowSpeed && ClientPrefs.timeBarType == 'Song Name') timeTxt.text = SONG.song + ' (' + playbackRateDecimal + 'x)'; - if (cpuControlled && ClientPrefs.timeBarType != 'Song Name' && !ClientPrefs.communityGameBot) timeTxt.text += ' (Bot)'; - if(ClientPrefs.timebarShowSpeed && cpuControlled && ClientPrefs.timeBarType == 'Song Name') timeTxt.text = SONG.song + ' (' + playbackRateDecimal + 'x) (Bot)'; - } - } - - if(updateThePercent) { - var curTime:Float = Conductor.songPosition - ClientPrefs.noteOffset; - if(curTime < 0) curTime = 0; - songPercent = (curTime / songLength); - songPercentThing = FlxMath.roundDecimal(curTime / songLength * 100, ClientPrefs.percentDecimals); - if (ClientPrefs.hudType != 'Kade Engine' && ClientPrefs.hudType != 'Dave and Bambi') - { - timePercentTxt.text = songPercentThing + '% Completed'; - } - else - { - timePercentTxt.text = songPercentThing + '%'; - } - } - - // Conductor.lastSongPos = FlxG.sound.music.time; - } - - if (camZooming) - { - FlxG.camera.zoom = FlxMath.lerp(defaultCamZoom, FlxG.camera.zoom, CoolUtil.boundTo(1 - (elapsed * 3.125 * camZoomingDecay * playbackRate), 0, 1)); - camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, CoolUtil.boundTo(1 - (elapsed * 3.125 * camZoomingDecay * playbackRate), 0, 1)); - } - - FlxG.watch.addQuick("secShit", curSection); - FlxG.watch.addQuick("beatShit", curBeat); - FlxG.watch.addQuick("stepShit", curStep); - - // RESET = Quick Game Over Screen - if (!ClientPrefs.noReset && controls.RESET && canReset && !inCutscene && startedCountdown && !endingSong && !softlocked) - { - health = 0; - trace("RESET = True"); - } - doDeathCheck(); - - if (ClientPrefs.dynamicSpawnTime) { - spawnTime = 1800 / songSpeed; - } else { - spawnTime = 1800 * ClientPrefs.noteSpawnTime; - } -if (unspawnNotes[0] != null && (Conductor.songPosition + 1800 / songSpeed) >= firstNoteStrumTime && ClientPrefs.showNotes) -{ - spawnTime /= unspawnNotes[0].multSpeed; - - // Track the count of notes added - notesAddedCount = 0; - - for (i in 0...unspawnNotes.length) { - var dunceNote = unspawnNotes[i]; - if (dunceNote.strumTime - Conductor.songPosition < spawnTime) { - if (ClientPrefs.showNotes) { - // Add notes to 'notes' one by one if they meet the criteria - notes.insert(0, dunceNote); - } else { - notes.add(dunceNote); - } - dunceNote.spawned = true; - notesAddedCount++; - } - } - - if (notesAddedCount > 0) { - unspawnNotes.splice(0, notesAddedCount); - } -} - -if (unspawnNotes[0] != null && (Conductor.songPosition + 1800 / songSpeed) >= firstNoteStrumTime && !ClientPrefs.showNotes) -{ - spawnTime /= unspawnNotes[0].multSpeed; - - // Track the count of notes added - notesAddedCount = 0; - - for (i in 0...unspawnNotes.length) { - var daNote = unspawnNotes[i]; - if(daNote.mustPress && cpuControlled) { - if (daNote.strumTime + (ClientPrefs.communityGameBot ? FlxG.random.float(ClientPrefs.minCGBMS, ClientPrefs.maxCGBMS) : 0) <= Conductor.songPosition || daNote.isSustainNote && daNote.strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * daNote.earlyHitMult /2)) { - if (!ClientPrefs.showcaseMode || ClientPrefs.charsAndBG) goodNoteHit(daNote); - if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG && !daNote.wasGoodHit) - { - if (!daNote.isSustainNote) { - totalNotesPlayed += 1 * polyphony; - if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well - notesHitArray.push(1 * polyphony); - notesHitDateArray.push(Date.now()); - } - } - } - daNote.wasGoodHit = true; - } - } - - if (!daNote.mustPress && !daNote.hitByOpponent && !daNote.ignoreNote && daNote.strumTime <= Conductor.songPosition) - { - if (!ClientPrefs.showcaseMode || ClientPrefs.charsAndBG) { - if (!opponentChart) { - if (Paths.formatToSongPath(SONG.song) != 'tutorial' && !camZooming) - camZooming = true; - } - - var char:Character = dad; - if(opponentChart) char = boyfriend; - if(daNote.noteType == 'Hey!' && char.animOffsets.exists('hey')) { - char.playAnim('hey', true); - char.specialAnim = true; - char.heyTimer = 0.6; - } else if(!daNote.noAnimation) { - var altAnim:String = daNote.animSuffix; - - if (SONG.notes[curSection] != null) - { - if (SONG.notes[curSection].altAnim && !SONG.notes[curSection].gfSection && !opponentChart) { - altAnim = '-alt'; - } - } - - var char:Character = dad; - var animToPlay:String = singAnimations[Std.int(Math.abs(daNote.noteData))] + altAnim; - if(daNote.gfNote && ClientPrefs.charsAndBG) { - char = gf; - if (ClientPrefs.doubleGhost) - { - if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) - { - // potentially have jump anims? - var chord = noteRows[daNote.mustPress?0:1][daNote.row]; - var animNote = chord[0]; - var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; - if (gf.mostRecentRow != daNote.row) - { - gf.playAnim(realAnim, true); - } - - // if (daNote != animNote) - // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); - - - gf.mostRecentRow = daNote.row; - // dad.angle += 15; lmaooooo - doGhostAnim('gf', animToPlay); - } - } - } - if(opponentChart && ClientPrefs.charsAndBG) { - boyfriend.playAnim(animToPlay, true); - boyfriend.holdTimer = 0; - } - else if(char != null && !opponentChart && ClientPrefs.charsAndBG) - { - char.playAnim(animToPlay, true); - char.holdTimer = 0; - if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'oppt'); - if (ClientPrefs.doubleGhost) - { - if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) - { - // potentially have jump anims? - var chord = noteRows[daNote.mustPress?0:1][daNote.row]; - var animNote = chord[0]; - var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; - if (char.mostRecentRow != daNote.row) - { - char.playAnim(realAnim, true); - } - - // if (daNote != animNote) - // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); - - // dad.angle += 15; lmaooooo - if (!daNote.noAnimation && !daNote.gfNote) - { - if(char.mostRecentRow != daNote.row) - doGhostAnim('char', animToPlay + altAnim); - dadGhost.color = FlxColor.fromRGB(dad.healthColorArray[0] + 50, dad.healthColorArray[1] + 50, dad.healthColorArray[2] + 50); - dadGhostTween = FlxTween.tween(dadGhost, {alpha: 0}, 0.75, { - ease: FlxEase.linear, - onComplete: function(twn:FlxTween) - { - dadGhostTween = null; - } - }); - } - char.mostRecentRow = daNote.row; - } - } - else{ - char.playAnim(animToPlay + daNote.animSuffix, true); - // dad.angle = 0; - } - } - if (opponentChart && ClientPrefs.charsAndBG) - { - boyfriend.playAnim(animToPlay + daNote.animSuffix, true); - boyfriend.holdTimer = 0; - if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'bf'); - if (ClientPrefs.doubleGhost) - { - if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) - { - // potentially have jump anims? - var chord = noteRows[daNote.mustPress?0:1][daNote.row]; - var animNote = chord[0]; - var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; - if (boyfriend.mostRecentRow != daNote.row) - { - boyfriend.playAnim(realAnim, true); - } - - // if (daNote != animNote) - // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); - - boyfriend.mostRecentRow = daNote.row; - // dad.angle += 15; lmaooooo - doGhostAnim('bf', animToPlay); - } - else{ - boyfriend.playAnim(animToPlay + daNote.animSuffix, true); - // dad.angle = 0; - } - } - } - } - - if(ClientPrefs.oppNoteSplashes && !daNote.isSustainNote) - { - spawnNoteSplashOnNote(true, daNote); - } - - if (SONG.needsVoices) - vocals.volume = 1; - - var time:Float = 0.15 / playbackRate; - if (ClientPrefs.opponentLightStrum) - { - if(daNote.isSustainNote && (ClientPrefs.showNotes && !daNote.animation.curAnim.name.endsWith('end'))) { - time += 0.15; - } - var spr:StrumNote = opponentStrums.members[daNote.noteData]; - - if(spr != null) { - if ((ClientPrefs.colorQuants || ClientPrefs.rainbowNotes) && ClientPrefs.showNotes) { - spr.playAnim('confirm', true, daNote.colorSwap.hue, daNote.colorSwap.saturation, daNote.colorSwap.brightness); - } else { - spr.playAnim('confirm', true); - } - spr.resetAnim = time; - } - } - daNote.hitByOpponent = true; - - if (opponentDrain && health > 0.1) health -= daNote.hitHealth * hpDrainLevel * polyphony; - - callOnLuas('opponentNoteHit', [notes.members.indexOf(daNote), Math.abs(daNote.noteData), daNote.noteType, daNote.isSustainNote]); - callOnLuas((opponentChart ? 'goodNoteHitFix' : 'opponentNoteHitFix'), [notes.members.indexOf(daNote), Math.abs(daNote.noteData), daNote.noteType, daNote.isSustainNote]); - - if (!daNote.isSustainNote) - { - if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well - oppNotesHitArray.push(1 * polyphony); - oppNotesHitDateArray.push(Date.now()); - } - enemyHits += 1 * polyphony; - if (shouldKillNotes) - { - daNote.kill(); - } - if (ClientPrefs.showNotes) notes.remove(daNote, true); - if (shouldKillNotes) - { - daNote.destroy(); - } - } - } - if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) - { - if (!daNote.isSustainNote) { - enemyHits += 1 * polyphony; - if (ClientPrefs.showNPS) { - oppNotesHitArray.push(1 * polyphony); - oppNotesHitDateArray.push(Date.now()); - } - } - daNote.hitByOpponent = true; - } - } - } - - if (notesAddedCount > 0) { - for (i in 0...notesAddedCount) - unspawnNotes.shift(); - } -} - if (generatedMusic) - { - if(!inCutscene) - { - if(!cpuControlled && !softlocked) { - keyShit(); - } - else if (ClientPrefs.charsAndBG) { - if(boyfriend.animation.curAnim != null && boyfriend.holdTimer > Conductor.stepCrochet * (0.0011 / playbackRate) * boyfriend.singDuration && boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss')) { - boyfriend.dance(); - //boyfriend.animation.curAnim.finish(); - } - if (dad.animation.curAnim != null && dad.holdTimer > Conductor.stepCrochet * (0.0011 / playbackRate) * dad.singDuration && dad.animation.curAnim.name.startsWith('sing') && !dad.animation.curAnim.name.endsWith('miss')) { - dad.dance(); - } - } - - if(startedCountdown) - { - var fakeCrochet:Float = (60 / SONG.bpm) * 1000; - notes.forEachAlive(function(daNote:Note) - { - if (ClientPrefs.showNotes) - { - var strumGroup:FlxTypedGroup = playerStrums; - if(!daNote.mustPress) strumGroup = opponentStrums; - - var strumX:Float = strumGroup.members[daNote.noteData].x; - var strumY:Float = strumGroup.members[daNote.noteData].y; - var strumAngle:Float = strumGroup.members[daNote.noteData].angle; - var strumDirection:Float = strumGroup.members[daNote.noteData].direction; - var strumAlpha:Float = strumGroup.members[daNote.noteData].alpha; - var strumScroll:Bool = strumGroup.members[daNote.noteData].downScroll; - - strumX += daNote.offsetX; - strumY += daNote.offsetY; - strumAngle += daNote.offsetAngle; - strumAlpha *= daNote.multAlpha; - - if (strumScroll) //Downscroll - { - //daNote.y = (strumY + 0.45 * (Conductor.songPosition - daNote.strumTime) * songSpeed); - daNote.distance = (0.45 * (Conductor.songPosition - daNote.strumTime) * songSpeed * daNote.multSpeed); - } - else //Upscroll - { - //daNote.y = (strumY - 0.45 * (Conductor.songPosition - daNote.strumTime) * songSpeed); - daNote.distance = (-0.45 * (Conductor.songPosition - daNote.strumTime) * songSpeed * daNote.multSpeed); - } - - var angleDir = strumDirection * Math.PI / 180; - if (daNote.copyAngle) - daNote.angle = strumDirection - 90 + strumAngle; - - if(daNote.copyAlpha) - daNote.alpha = strumAlpha; - - if(daNote.copyX) - daNote.x = strumX + Math.cos(angleDir) * daNote.distance; - - if(daNote.copyY) - { - daNote.y = strumY + Math.sin(angleDir) * daNote.distance; - - //Jesus fuck this took me so much mother fucking time AAAAAAAAAA - if(strumScroll && daNote.isSustainNote && ClientPrefs.showNotes) - { - if (daNote.animation.curAnim.name.endsWith('end')) { - daNote.y += 10.5 * (fakeCrochet / 400) * 1.5 * songSpeed + (46 * (songSpeed - 1)); - daNote.y -= 46 * (1 - (fakeCrochet / 600)) * songSpeed; - if(PlayState.isPixelStage) { - daNote.y += 8 + (6 - daNote.originalHeightForCalcs) * PlayState.daPixelZoom; - } else { - daNote.y -= 19; - } - } - daNote.y += (Note.swagWidth / 2) - (60.5 * (songSpeed - 1)); - daNote.y += 27.5 * ((SONG.bpm / 100) - 1) * (songSpeed - 1); - } - } - var center:Float = strumY + Note.swagWidth / 2; - if(strumGroup.members[daNote.noteData].sustainReduce && daNote.isSustainNote && (daNote.mustPress || !daNote.ignoreNote) && - (!daNote.mustPress || (daNote.wasGoodHit || (daNote.prevNote.wasGoodHit && !daNote.canBeHit)))) - { - if (strumScroll) - { - if(daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= center) - { - var swagRect = new FlxRect(0, 0, daNote.frameWidth, daNote.frameHeight); - swagRect.height = (center - daNote.y) / daNote.scale.y; - swagRect.y = daNote.frameHeight - swagRect.height; - - daNote.clipRect = swagRect; - } - } - else - { - if (daNote.y + daNote.offset.y * daNote.scale.y <= center) - { - var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y); - swagRect.y = (center - daNote.y) / daNote.scale.y; - swagRect.height -= swagRect.y; - - daNote.clipRect = swagRect; - } - } - } - } - - if (!daNote.mustPress && !daNote.hitByOpponent && !daNote.ignoreNote && daNote.strumTime <= Conductor.songPosition) - { - if (!ClientPrefs.showcaseMode || ClientPrefs.charsAndBG) { - if (!opponentChart) { - if (Paths.formatToSongPath(SONG.song) != 'tutorial' && !camZooming) - camZooming = true; - } - - var char:Character = dad; - if(opponentChart) char = boyfriend; - if(daNote.noteType == 'Hey!' && char.animOffsets.exists('hey')) { - char.playAnim('hey', true); - char.specialAnim = true; - char.heyTimer = 0.6; - } else if(!daNote.noAnimation) { - var altAnim:String = daNote.animSuffix; - - if (SONG.notes[curSection] != null) - { - if (SONG.notes[curSection].altAnim && !SONG.notes[curSection].gfSection && !opponentChart) { - altAnim = '-alt'; - } - } - - var char:Character = dad; - var animToPlay:String = singAnimations[Std.int(Math.abs(daNote.noteData))] + altAnim; - if(daNote.gfNote && ClientPrefs.charsAndBG) { - char = gf; - if (ClientPrefs.doubleGhost) - { - if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) - { - // potentially have jump anims? - var chord = noteRows[daNote.mustPress?0:1][daNote.row]; - var animNote = chord[0]; - var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; - if (gf.mostRecentRow != daNote.row) - { - gf.playAnim(realAnim, true); - } - - // if (daNote != animNote) - // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); - - - gf.mostRecentRow = daNote.row; - // dad.angle += 15; lmaooooo - doGhostAnim('gf', animToPlay); - } - } - } - if(opponentChart && ClientPrefs.charsAndBG) { - boyfriend.playAnim(animToPlay, true); - boyfriend.holdTimer = 0; - } - else if(char != null && !opponentChart && ClientPrefs.charsAndBG) - { - char.playAnim(animToPlay, true); - char.holdTimer = 0; - if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'oppt'); - if (ClientPrefs.doubleGhost) - { - if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) - { - // potentially have jump anims? - var chord = noteRows[daNote.mustPress?0:1][daNote.row]; - var animNote = chord[0]; - var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; - if (char.mostRecentRow != daNote.row) - { - char.playAnim(realAnim, true); - } - - // if (daNote != animNote) - // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); - - // dad.angle += 15; lmaooooo - if (!daNote.noAnimation && !daNote.gfNote) - { - if(char.mostRecentRow != daNote.row) - doGhostAnim('char', animToPlay + altAnim); - dadGhost.color = FlxColor.fromRGB(dad.healthColorArray[0] + 50, dad.healthColorArray[1] + 50, dad.healthColorArray[2] + 50); - dadGhostTween = FlxTween.tween(dadGhost, {alpha: 0}, 0.75, { - ease: FlxEase.linear, - onComplete: function(twn:FlxTween) - { - dadGhostTween = null; - } - }); - } - char.mostRecentRow = daNote.row; - } - } - else{ - char.playAnim(animToPlay + daNote.animSuffix, true); - // dad.angle = 0; - } - } - if (opponentChart && ClientPrefs.charsAndBG) - { - boyfriend.playAnim(animToPlay + daNote.animSuffix, true); - boyfriend.holdTimer = 0; - if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'bf'); - if (ClientPrefs.doubleGhost) - { - if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) - { - // potentially have jump anims? - var chord = noteRows[daNote.mustPress?0:1][daNote.row]; - var animNote = chord[0]; - var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; - if (boyfriend.mostRecentRow != daNote.row) - { - boyfriend.playAnim(realAnim, true); - } - - // if (daNote != animNote) - // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); - - boyfriend.mostRecentRow = daNote.row; - // dad.angle += 15; lmaooooo - doGhostAnim('bf', animToPlay); - } - else{ - boyfriend.playAnim(animToPlay + daNote.animSuffix, true); - // dad.angle = 0; - } - } - } - } - - if(ClientPrefs.oppNoteSplashes && !daNote.isSustainNote) - { - spawnNoteSplashOnNote(true, daNote); - } - - if (SONG.needsVoices) - vocals.volume = 1; - - var time:Float = 0.15 / playbackRate; - if (ClientPrefs.opponentLightStrum) - { - if(daNote.isSustainNote && (ClientPrefs.showNotes && !daNote.animation.curAnim.name.endsWith('end'))) { - time += 0.15; - } - var spr:StrumNote = opponentStrums.members[daNote.noteData]; - - if(spr != null) { - if ((ClientPrefs.colorQuants || ClientPrefs.rainbowNotes) && ClientPrefs.showNotes) { - spr.playAnim('confirm', true, daNote.colorSwap.hue, daNote.colorSwap.saturation, daNote.colorSwap.brightness); - } else { - spr.playAnim('confirm', true); - } - spr.resetAnim = time; - } - } - daNote.hitByOpponent = true; - - if (opponentDrain && health > 0.1) health -= daNote.hitHealth * hpDrainLevel * polyphony; - - callOnLuas('opponentNoteHit', [notes.members.indexOf(daNote), Math.abs(daNote.noteData), daNote.noteType, daNote.isSustainNote]); - callOnLuas((opponentChart ? 'goodNoteHitFix' : 'opponentNoteHitFix'), [notes.members.indexOf(daNote), Math.abs(daNote.noteData), daNote.noteType, daNote.isSustainNote]); - - if (!daNote.isSustainNote) - { - if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well - oppNotesHitArray.push(1 * polyphony); - oppNotesHitDateArray.push(Date.now()); - } - enemyHits += 1 * polyphony; - if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0) updateRatingCounter(); - if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); - if (shouldKillNotes) - { - daNote.kill(); - } - if (ClientPrefs.showNotes) notes.remove(daNote, true); - if (shouldKillNotes) - { - daNote.destroy(); - } - } - } - if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) - { - if (!daNote.isSustainNote) { - enemyHits += 1 * polyphony; - if (ClientPrefs.showNPS) { - oppNotesHitArray.push(1 * polyphony); - oppNotesHitDateArray.push(Date.now()); - } - } - if (!daNote.isSustainNote) { - if (shouldKillNotes) - { - daNote.kill(); - } - if (shouldKillNotes) - { - daNote.destroy(); - } - } - } - } - - if(daNote.mustPress && cpuControlled) { - if(daNote.strumTime + (ClientPrefs.communityGameBot ? FlxG.random.float(ClientPrefs.minCGBMS, ClientPrefs.maxCGBMS) : 0) <= Conductor.songPosition || daNote.isSustainNote && daNote.strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * daNote.earlyHitMult /2)) { - if (!ClientPrefs.showcaseMode || ClientPrefs.charsAndBG) goodNoteHit(daNote); - if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) - { - if (!daNote.isSustainNote) { - totalNotesPlayed += 1 * polyphony; - if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well - notesHitArray.push(1 * polyphony); - notesHitDateArray.push(Date.now()); - } - if (shouldKillNotes) - { - daNote.kill(); - } - if (shouldKillNotes) - { - daNote.destroy(); - } - } - } - } - } - - // Kill extremely late notes and cause misses - if (Conductor.songPosition > noteKillOffset + daNote.strumTime) - { - if (daNote.mustPress && (!cpuControlled || cpuControlled && ClientPrefs.communityGameBot) &&!daNote.ignoreNote && !endingSong && (daNote.tooLate || !daNote.wasGoodHit)) { - noteMiss(daNote); - if (ClientPrefs.missSoundShit) - { - FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); - } - } - - daNote.active = false; - daNote.visible = false; - if (shouldKillNotes) - { - daNote.kill(); - } - notes.remove(daNote, true); - if (shouldKillNotes) - { - daNote.destroy(); - } - } - }); - } - else - { - notes.forEachAlive(function(daNote:Note) - { - daNote.canBeHit = false; - daNote.wasGoodHit = false; - }); - } - } - checkEventNote(); - } - - #if debug - if(!endingSong && !startingSong) { - if (FlxG.keys.justPressed.ONE) { - KillNotes(); - if (ClientPrefs.songLoading) FlxG.sound.music.onComplete(); - } - if(FlxG.keys.justPressed.TWO) { //Go 10 seconds into the future :O - setSongTime(Conductor.songPosition + 10000); - clearNotesBefore(Conductor.songPosition); - } - if(FlxG.keys.justPressed.THREE) { //Go 10 seconds into the future :O - setSongTime(Conductor.songPosition - 10000); - clearNotesBefore(Conductor.songPosition); - } - } - #end - - setOnLuas('cameraX', camFollowPos.x); - setOnLuas('cameraY', camFollowPos.y); - setOnLuas('botPlay', cpuControlled); - callOnLuas('onUpdatePost', [elapsed]); - for (i in shaderUpdates){ - i(elapsed); - } - } - - function openPauseMenu() - { - persistentUpdate = false; - persistentDraw = true; - paused = true; - - // 1 / 1000 chance for Gitaroo Man easter egg - /*if (FlxG.random.bool(0.1)) - { - // gitaroo man easter egg - cancelMusicFadeTween(); - MusicBeatState.switchState(new GitarooPause()); - } - else {*/ - if(FlxG.sound.music != null && ClientPrefs.songLoading) { - FlxG.sound.music.pause(); - vocals.pause(); - } - if (!ClientPrefs.charsAndBG) openSubState(new PauseSubState(0, 0)); - if (ClientPrefs.charsAndBG) openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); - //} - - #if desktop - DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); - #end - } - - function openChartEditor() - { - persistentUpdate = false; - paused = true; - cancelMusicFadeTween(); - MusicBeatState.switchState(new ChartingState()); - chartingMode = true; - #if desktop - DiscordClient.changePresence("Chart Editor", null, null, true); - #end - } - - public var isDead:Bool = false; //Don't mess with this on Lua!!! - function doDeathCheck(?skipHealthCheck:Bool = false) { - if (((skipHealthCheck && instakillOnMiss) || health <= 0) && !practiceMode && !isDead) - { - if (ClientPrefs.instaRestart) - { - restartSong(true); - } - var ret:Dynamic = callOnLuas('onGameOver', [], false); - if(ret != FunkinLua.Function_Stop) { - boyfriend.stunned = true; - deathCounter++; - - paused = true; - - if (ClientPrefs.songLoading) vocals.stop(); - if (ClientPrefs.songLoading) FlxG.sound.music.stop(); - - persistentUpdate = false; - persistentDraw = false; - for (tween in modchartTweens) { - tween.active = true; - } - for (timer in modchartTimers) { - timer.active = true; - } - if (ClientPrefs.charsAndBG) openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x - boyfriend.positionArray[0], boyfriend.getScreenPosition().y - boyfriend.positionArray[1], camFollowPos.x, camFollowPos.y)); - - if (!ClientPrefs.charsAndBG) openSubState(new GameOverSubstate(0, 0, 0, 0)); - - // MusicBeatState.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); - - #if desktop - // Game Over doesn't get his own variable because it's only used here - DiscordClient.changePresence("Game Over - " + detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); - #end - isDead = true; - return true; - } - } - return false; - } - - public function checkEventNote() { - while(eventNotes.length > 0) { - var leStrumTime:Float = eventNotes[0].strumTime; - if(Conductor.songPosition < leStrumTime) { - return; - } - - var value1:String = ''; - if(eventNotes[0].value1 != null) - value1 = eventNotes[0].value1; - - var value2:String = ''; - if(eventNotes[0].value2 != null) - value2 = eventNotes[0].value2; - - triggerEventNote(eventNotes[0].event, value1, value2); - eventNotes.shift(); - } - } - - public function getControl(key:String) { - var pressed:Bool = Reflect.getProperty(controls, key); - //trace('Control result: ' + pressed); - return pressed; - } - - public function triggerEventNote(eventName:String, value1:String, value2:String) { - switch(eventName) { - case 'Dadbattle Spotlight': - var val:Null = Std.parseInt(value1); - if(val == null) val = 0; - - switch(Std.parseInt(value1)) - { - case 1, 2, 3: //enable and target dad - if(val == 1) //enable - { - dadbattleBlack.visible = true; - dadbattleLight.visible = true; - dadbattleSmokes.visible = true; - defaultCamZoom += 0.12; - } - - var who:Character = dad; - if(val > 2) who = boyfriend; - //2 only targets dad - dadbattleLight.alpha = 0; - new FlxTimer().start(0.12, function(tmr:FlxTimer) { - dadbattleLight.alpha = 0.375; - }); - dadbattleLight.setPosition(who.getGraphicMidpoint().x - dadbattleLight.width / 2, who.y + who.height - dadbattleLight.height + 50); - - default: - dadbattleBlack.visible = false; - dadbattleLight.visible = false; - defaultCamZoom -= 0.12; - FlxTween.tween(dadbattleSmokes, {alpha: 0}, 1, {onComplete: function(twn:FlxTween) - { - dadbattleSmokes.visible = false; - }}); - } - - case 'Hey!': - if (ClientPrefs.charsAndBG) { - var value:Int = 2; - switch(value1.toLowerCase().trim()) { - case 'bf' | 'boyfriend' | '0': - value = 0; - case 'gf' | 'girlfriend' | '1': - value = 1; - } - - var time:Float = Std.parseFloat(value2); - if(Math.isNaN(time) || time <= 0) time = 0.6; - - if(value != 0) { - if(dad.curCharacter.startsWith('gf')) { //Tutorial GF is actually Dad! The GF is an imposter!! ding ding ding ding ding ding ding, dindinding, end my suffering - dad.playAnim('cheer', true); - dad.specialAnim = true; - dad.heyTimer = time; - } else if (gf != null) { - gf.playAnim('cheer', true); - gf.specialAnim = true; - gf.heyTimer = time; - } - - if(curStage == 'mall') { - bottomBoppers.animation.play('hey', true); - heyTimer = time; - } - } - if(value != 1) { - boyfriend.playAnim('hey', true); - boyfriend.specialAnim = true; - boyfriend.heyTimer = time; - } - } - - case 'Set GF Speed': - var value:Int = Std.parseInt(value1); - if(Math.isNaN(value) || value < 1) value = 1; - gfSpeed = value; - - case 'Philly Glow': - var lightId:Int = Std.parseInt(value1); - if(Math.isNaN(lightId)) lightId = 0; - - var doFlash:Void->Void = function() { - var color:FlxColor = FlxColor.WHITE; - if(!ClientPrefs.flashing) color.alphaFloat = 0.5; - - FlxG.camera.flash(color, 0.15, null, true); - }; - - var chars:Array = [boyfriend, gf, dad]; - switch(lightId) - { - case 0: - if(phillyGlowGradient.visible) - { - doFlash(); - if(ClientPrefs.camZooms) - { - FlxG.camera.zoom += 0.5; - camHUD.zoom += 0.1; - } - - blammedLightsBlack.visible = false; - phillyWindowEvent.visible = false; - phillyGlowGradient.visible = false; - phillyGlowParticles.visible = false; - curLightEvent = -1; - - for (who in chars) - { - who.color = FlxColor.WHITE; - } - phillyStreet.color = FlxColor.WHITE; - } - - case 1: //turn on - curLightEvent = FlxG.random.int(0, phillyLightsColors.length-1, [curLightEvent]); - var color:FlxColor = phillyLightsColors[curLightEvent]; - - if(!phillyGlowGradient.visible) - { - doFlash(); - if(ClientPrefs.camZooms) - { - FlxG.camera.zoom += 0.5; - camHUD.zoom += 0.1; - } - - blammedLightsBlack.visible = true; - blammedLightsBlack.alpha = 1; - phillyWindowEvent.visible = true; - phillyGlowGradient.visible = true; - phillyGlowParticles.visible = true; - } - else if(ClientPrefs.flashing) - { - var colorButLower:FlxColor = color; - colorButLower.alphaFloat = 0.25; - FlxG.camera.flash(colorButLower, 0.5, null, true); - } - - var charColor:FlxColor = color; - if(!ClientPrefs.flashing) charColor.saturation *= 0.5; - else charColor.saturation *= 0.75; - - for (who in chars) - { - who.color = charColor; - } - phillyGlowParticles.forEachAlive(function(particle:PhillyGlow.PhillyGlowParticle) - { - particle.color = color; - }); - phillyGlowGradient.color = color; - phillyWindowEvent.color = color; - - color.brightness *= 0.5; - phillyStreet.color = color; - - case 2: // spawn particles - if(!ClientPrefs.lowQuality) - { - var particlesNum:Int = FlxG.random.int(8, 12); - var width:Float = (2000 / particlesNum); - var color:FlxColor = phillyLightsColors[curLightEvent]; - for (j in 0...3) - { - for (i in 0...particlesNum) - { - var particle:PhillyGlow.PhillyGlowParticle = new PhillyGlow.PhillyGlowParticle(-400 + width * i + FlxG.random.float(-width / 5, width / 5), phillyGlowGradient.originalY + 200 + (FlxG.random.float(0, 125) + j * 40), color); - phillyGlowParticles.add(particle); - } - } - } - phillyGlowGradient.bop(); - } - - case 'Kill Henchmen': - killHenchmen(); - - case 'Enable Camera Bop': - camZooming = true; - - case 'Disable Camera Bop': - camZooming = false; - - case 'Camera Bopping': - var _interval:Int = Std.parseInt(value1); - if (Math.isNaN(_interval)) - _interval = 4; - var _intensity:Float = Std.parseFloat(value2); - if (Math.isNaN(_intensity)) - _intensity = 1; - - camBopIntensity = _intensity; - camBopInterval = _interval; - case 'Change Note Multiplier': - var noteMultiplier:Float = Std.parseFloat(value1); - if (Math.isNaN(noteMultiplier)) - noteMultiplier = 1; - - polyphony = noteMultiplier; - case 'Fake Song Length': - var fakelength:Float = Std.parseFloat(value1); - fakelength *= (Math.isNaN(fakelength) ? 1 : 1000); //don't multiply if value1 is null, but do if value1 is not null - var doTween:Bool = value2 == "true" ? true : false; - if (Math.isNaN(fakelength)) - if (ClientPrefs.songLoading) fakelength = FlxG.sound.music.length; - if (doTween = true) FlxTween.tween(this, {songLength: fakelength}, 1, {ease: FlxEase.expoOut}); - if (doTween = true && ClientPrefs.songLoading && (Math.isNaN(fakelength))) FlxTween.tween(this, {songLength: FlxG.sound.music.length}, 1, {ease: FlxEase.expoOut}); - songLength = fakelength; - - case 'Add Camera Zoom': - if(ClientPrefs.camZooms && FlxG.camera.zoom < 1.35) { - var camZoom:Float = Std.parseFloat(value1); - var hudZoom:Float = Std.parseFloat(value2); - if(Math.isNaN(camZoom)) camZoom = 0.015; - if(Math.isNaN(hudZoom)) hudZoom = 0.03; - - FlxG.camera.zoom += camZoom; - camHUD.zoom += hudZoom; - } - - case 'Trigger BG Ghouls': - if(curStage == 'schoolEvil' && !ClientPrefs.lowQuality) { - bgGhouls.dance(true); - bgGhouls.visible = true; - } - case 'Play Animation': - //trace('Anim to play: ' + value1); - var char:Character = dad; - switch(value2.toLowerCase().trim()) { - case 'bf' | 'boyfriend': - char = boyfriend; - case 'gf' | 'girlfriend': - char = gf; - default: - var val2:Int = Std.parseInt(value2); - if(Math.isNaN(val2)) val2 = 0; - - switch(val2) { - case 1: char = boyfriend; - case 2: char = gf; - } - } - - if (char != null) - { - char.playAnim(value1, true); - char.specialAnim = true; - } - - case 'Camera Follow Pos': - if(camFollow != null) - { - var val1:Float = Std.parseFloat(value1); - var val2:Float = Std.parseFloat(value2); - if(Math.isNaN(val1)) val1 = 0; - if(Math.isNaN(val2)) val2 = 0; - - isCameraOnForcedPos = false; - if(!Math.isNaN(Std.parseFloat(value1)) || !Math.isNaN(Std.parseFloat(value2))) { - camFollow.x = val1; - camFollow.y = val2; - isCameraOnForcedPos = true; - } - } - - case 'Alt Idle Animation': - var char:Character = dad; - switch(value1.toLowerCase().trim()) { - case 'gf' | 'girlfriend': - char = gf; - case 'boyfriend' | 'bf': - char = boyfriend; - default: - var val:Int = Std.parseInt(value1); - if(Math.isNaN(val)) val = 0; - - switch(val) { - case 1: char = boyfriend; - case 2: char = gf; - } - } - - if (char != null) - { - char.idleSuffix = value2; - char.recalculateDanceIdle(); - } - - case 'Screen Shake': - var valuesArray:Array = [value1, value2]; - var targetsArray:Array = [camGame, camHUD]; - for (i in 0...targetsArray.length) { - var split:Array = valuesArray[i].split(','); - var duration:Float = 0; - var intensity:Float = 0; - if(split[0] != null) duration = Std.parseFloat(split[0].trim()); - if(split[1] != null) intensity = Std.parseFloat(split[1].trim()); - if(Math.isNaN(duration)) duration = 0; - if(Math.isNaN(intensity)) intensity = 0; - - if(duration > 0 && intensity != 0) { - targetsArray[i].shake(intensity, duration); - } - } - - - case 'Change Character': - var charType:Int = 0; - switch(value1.toLowerCase().trim()) { - case 'gf' | 'girlfriend': - charType = 2; - case 'dad' | 'opponent': - charType = 1; - default: - charType = Std.parseInt(value1); - if(Math.isNaN(charType)) charType = 0; - } - - switch(charType) { - case 0: - if(boyfriend.curCharacter != value2) { - if(!boyfriendMap.exists(value2)) { - addCharacterToList(value2, charType); - } - - var lastAlpha:Float = boyfriend.alpha; - boyfriend.alpha = 0.00001; - boyfriend = boyfriendMap.get(value2); - boyfriend.alpha = lastAlpha; - iconP1.changeIcon(boyfriend.healthIcon); - } - setOnLuas('boyfriendName', boyfriend.curCharacter); - - case 1: - if(dad.curCharacter != value2) { - if(!dadMap.exists(value2)) { - addCharacterToList(value2, charType); - } - - var wasGf:Bool = dad.curCharacter.startsWith('gf'); - var lastAlpha:Float = dad.alpha; - dad.alpha = 0.00001; - dad = dadMap.get(value2); - if(!dad.curCharacter.startsWith('gf')) { - if(wasGf && gf != null) { - gf.visible = true; - } - } else if(gf != null) { - gf.visible = false; - } - dad.alpha = lastAlpha; - iconP2.changeIcon(dad.healthIcon); - if (ClientPrefs.hudType == 'VS Impostor') { - if (botplayTxt != null) FlxTween.color(botplayTxt, 1, botplayTxt.color, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])); - - if (!ClientPrefs.hideScore) FlxTween.color(scoreTxt, 1, scoreTxt.color, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])); - } - if (ClientPrefs.hudType == 'JS Engine') { - if (!ClientPrefs.hideScore) FlxTween.color(scoreTxt, 1, scoreTxt.color, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])); - } - } - setOnLuas('dadName', dad.curCharacter); - - case 2: - if(gf != null) - { - if(gf.curCharacter != value2) - { - if(!gfMap.exists(value2)) - { - addCharacterToList(value2, charType); - } - - var lastAlpha:Float = gf.alpha; - gf.alpha = 0.00001; - gf = gfMap.get(value2); - gf.alpha = lastAlpha; - } - setOnLuas('gfName', gf.curCharacter); - } - } - reloadHealthBarColors(); - - case 'BG Freaks Expression': - if(bgGirls != null) bgGirls.swapDanceType(); - - case 'Change Scroll Speed': - if (songSpeedType == "constant") - return; - var val1:Float = Std.parseFloat(value1); - var val2:Float = Std.parseFloat(value2); - if(Math.isNaN(val1)) val1 = 1; - if(Math.isNaN(val2)) val2 = 0; - - var newValue:Float = SONG.speed * ClientPrefs.getGameplaySetting('scrollspeed', 1) * val1; - - if(val2 <= 0) - { - songSpeed = newValue; - } - else - { - songSpeedTween = FlxTween.tween(this, {songSpeed: newValue}, val2 / playbackRate, {ease: FlxEase.linear, onComplete: - function (twn:FlxTween) - { - songSpeedTween = null; - } - }); - } - - case 'Set Property': - var killMe:Array = value1.split('.'); - if(killMe.length > 1) { - FunkinLua.setVarInArray(FunkinLua.getPropertyLoopThingWhatever(killMe, true, true), killMe[killMe.length-1], value2); - } else { - FunkinLua.setVarInArray(this, value1, value2); - } - } - callOnLuas('onEvent', [eventName, value1, value2]); - } - - function moveCameraSection():Void { - if(SONG.notes[curSection] == null) return; - - if (gf != null && SONG.notes[curSection].gfSection) - { - camFollow.set(gf.getMidpoint().x, gf.getMidpoint().y); - camFollow.x += gf.cameraPosition[0] + girlfriendCameraOffset[0]; - camFollow.y += gf.cameraPosition[1] + girlfriendCameraOffset[1]; - tweenCamIn(); - callOnLuas('onMoveCamera', ['gf']); - return; - } - - if (!SONG.notes[curSection].mustHitSection) - { - moveCamera(true); - callOnLuas('onMoveCamera', ['dad']); - } - else - { - moveCamera(false); - callOnLuas('onMoveCamera', ['boyfriend']); - } - } - - var cameraTwn:FlxTween; - public function moveCamera(isDad:Bool) - { - if(isDad) - { - camFollow.set(dad.getMidpoint().x + 150, dad.getMidpoint().y - 100); - camFollow.x += dad.cameraPosition[0] + opponentCameraOffset[0]; - camFollow.y += dad.cameraPosition[1] + opponentCameraOffset[1]; - tweenCamIn(); - } - else - { - camFollow.set(boyfriend.getMidpoint().x - 100, boyfriend.getMidpoint().y - 100); - camFollow.x -= boyfriend.cameraPosition[0] - boyfriendCameraOffset[0]; - camFollow.y += boyfriend.cameraPosition[1] + boyfriendCameraOffset[1]; - - if (Paths.formatToSongPath(SONG.song) == 'tutorial' && cameraTwn == null && FlxG.camera.zoom != 1) - { - cameraTwn = FlxTween.tween(FlxG.camera, {zoom: 1}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut, onComplete: - function (twn:FlxTween) - { - cameraTwn = null; - } - }); - } - } - } - - function tweenCamIn() { - if (Paths.formatToSongPath(SONG.song) == 'tutorial' && cameraTwn == null && FlxG.camera.zoom != 1.3) { - cameraTwn = FlxTween.tween(FlxG.camera, {zoom: 1.3}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut, onComplete: - function (twn:FlxTween) { - cameraTwn = null; - } - }); - } - } - - function snapCamFollowToPos(x:Float, y:Float) { - camFollow.set(x, y); - camFollowPos.setPosition(x, y); - } - - public function finishSong(?ignoreNoteOffset:Bool = false):Void - { - var finishCallback:Void->Void = endSong; //In case you want to change it in a specific song. - updateTime = false; - if (ClientPrefs.songLoading) FlxG.sound.music.volume = 0; - if (ClientPrefs.songLoading) vocals.volume = 0; - vocals.pause(); - if(ClientPrefs.noteOffset <= 0 || ignoreNoteOffset) { - finishCallback(); - } else { - finishTimer = new FlxTimer().start(ClientPrefs.noteOffset / 1000, function(tmr:FlxTimer) { - finishCallback(); - }); - } - } - public function no(?ignoreNoteOffset:Bool = false):Void - { - var loopedSong:Int = 1; - if (ClientPrefs.songLoading) FlxG.sound.music.volume = 0; - if (ClientPrefs.songLoading) vocals.volume = 0; - Conductor.songPosition = 8000 * loopedSong; - loopedSong++; - } - public function loopSongNoLimit(?ignoreNoteOffset:Bool = false):Void - { - if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; - if (!ClientPrefs.voiidTrollMode) { - if (playbackRate >= 65535) playbackRate += 3276.7; - if (playbackRate >= 32767 && playbackRate <= 65535) playbackRate += 1638.4; - if (playbackRate >= 16384 && playbackRate <= 32767) playbackRate += 819.2; - if (playbackRate >= 8192 && playbackRate <= 16384) playbackRate += 409.6; - if (playbackRate >= 4096 && playbackRate <= 8192) playbackRate += 204.8; - if (playbackRate >= 2048 && playbackRate <= 4096) playbackRate += 102.4; - if (playbackRate >= 1024 && playbackRate <= 2048) playbackRate += 51.2; - if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; - if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; - if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; - if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; - if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; - if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; - if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; - if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; - if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; - if (playbackRate <= 2) playbackRate += 0.05; - } - unspawnNotes = unspawnNotesCopy.copy(); - for (n in unspawnNotes) - { - n.active = true; - n.visible = true; - n.wasGoodHit = false; - n.canBeHit = false; - n.tooLate = false; - n.hitByOpponent = false; - n.spawned = false; - n.alpha = 1; - if (n.mustPress && !n.isSustainNote) - { - totalNotes += 1; - } else if (!n.mustPress && !n.isSustainNote) { - opponentNoteTotal += 1; - } - } - Conductor.songPosition = 0; - } - public function loopSongHighest(?ignoreNoteOffset:Bool = false):Void - { - if (playbackRate >= 10000) playbackRate = 10000; - if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; - if (!ClientPrefs.voiidTrollMode) { - if (playbackRate >= 5120 && playbackRate <= 10000) playbackRate += 409.6; - if (playbackRate >= 4096 && playbackRate <= 5120) playbackRate += 204.8; - if (playbackRate >= 2048 && playbackRate <= 4096) playbackRate += 102.4; - if (playbackRate >= 1024 && playbackRate <= 2048) playbackRate += 51.2; - if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; - if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; - if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; - if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; - if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; - if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; - if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; - if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; - if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; - if (playbackRate <= 2) playbackRate += 0.05; - } - unspawnNotes = unspawnNotesCopy.copy(); - for (n in unspawnNotes) - { - n.active = true; - n.visible = true; - n.wasGoodHit = false; - n.canBeHit = false; - n.tooLate = false; - n.hitByOpponent = false; - n.spawned = false; - n.alpha = 1; - if (n.mustPress && !n.isSustainNote) - { - totalNotes += 1; - } else if (!n.mustPress && !n.isSustainNote) { - opponentNoteTotal += 1; - } - } - Conductor.songPosition = 0; - } - public function loopSongHigh(?ignoreNoteOffset:Bool = false):Void - { - if (playbackRate >= 5120) playbackRate = 5120; - if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; - if (!ClientPrefs.voiidTrollMode) { - if (playbackRate >= 4096 && playbackRate <= 5119.99) playbackRate += 204.8; - if (playbackRate >= 2048 && playbackRate <= 4096) playbackRate += 102.4; - if (playbackRate >= 1024 && playbackRate <= 2048) playbackRate += 51.2; - if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; - if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; - if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; - if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; - if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; - if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; - if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; - if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; - if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; - if (playbackRate <= 2) playbackRate += 0.05; - } - unspawnNotes = unspawnNotesCopy.copy(); - for (n in unspawnNotes) - { - n.active = true; - n.visible = true; - n.wasGoodHit = false; - n.canBeHit = false; - n.tooLate = false; - n.hitByOpponent = false; - n.spawned = false; - n.alpha = 1; - if (n.mustPress && !n.isSustainNote) - { - totalNotes += 1; - } else if (!n.mustPress && !n.isSustainNote) { - opponentNoteTotal += 1; - } - } - Conductor.songPosition = 0; - } - public function loopSongMedium(?ignoreNoteOffset:Bool = false):Void - { - if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; - if (playbackRate >= 2048) playbackRate = 2048; - if (!ClientPrefs.voiidTrollMode) { - if (playbackRate >= 1024 && playbackRate <= 2047.99) playbackRate += 51.2; - if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; - if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; - if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; - if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; - if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; - if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; - if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; - if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; - if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; - if (playbackRate <= 2) playbackRate += 0.05; - } - unspawnNotes = unspawnNotesCopy.copy(); - for (n in unspawnNotes) - { - n.active = true; - n.visible = true; - n.wasGoodHit = false; - n.canBeHit = false; - n.tooLate = false; - n.hitByOpponent = false; - n.spawned = false; - n.alpha = 1; - if (n.mustPress && !n.isSustainNote) - { - totalNotes += 1; - } else if (!n.mustPress && !n.isSustainNote) { - opponentNoteTotal += 1; - } - } - Conductor.songPosition = 0; - } - public function loopSongLow(?ignoreNoteOffset:Bool = false):Void - { - if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; - if (playbackRate >= 1024) playbackRate = 1024; - if (!ClientPrefs.voiidTrollMode) { - if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; - if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; - if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; - if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; - if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; - if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; - if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; - if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; - if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; - if (playbackRate <= 2) playbackRate += 0.05; - } - unspawnNotes = unspawnNotesCopy.copy(); - for (n in unspawnNotes) - { - n.active = true; - n.visible = true; - n.wasGoodHit = false; - n.canBeHit = false; - n.tooLate = false; - n.hitByOpponent = false; - n.spawned = false; - n.alpha = 1; - if (n.mustPress && !n.isSustainNote) - { - totalNotes += 1; - } else if (!n.mustPress && !n.isSustainNote) { - opponentNoteTotal += 1; - } - } - Conductor.songPosition = 0; - } - public function loopSongLower(?ignoreNoteOffset:Bool = false):Void - { - if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; - if (playbackRate >= 512) playbackRate = 512; - if (!ClientPrefs.voiidTrollMode) { - if (playbackRate >= 256 && playbackRate <= 511.9) playbackRate += 12.8; - if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; - if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; - if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; - if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; - if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; - if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; - if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; - if (playbackRate <= 2) playbackRate += 0.05; - } - unspawnNotes = unspawnNotesCopy.copy(); - for (n in unspawnNotes) - { - n.active = true; - n.visible = true; - n.wasGoodHit = false; - n.canBeHit = false; - n.tooLate = false; - n.hitByOpponent = false; - n.spawned = false; - n.alpha = 1; - n.clipRect = null; - if (n.mustPress && !n.isSustainNote) - { - totalNotes += 1; - } else if (!n.mustPress && !n.isSustainNote) { - opponentNoteTotal += 1; - } - } - Conductor.songPosition = 0; - } - public function loopSongLowest(?ignoreNoteOffset:Bool = false):Void - { - if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; - if (playbackRate >= 256) playbackRate = 256; - if (!ClientPrefs.voiidTrollMode) { - if (playbackRate >= 128 && playbackRate <= 255) playbackRate += 6.4; - if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; - if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; - if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; - if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; - if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; - if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; - if (playbackRate <= 2) playbackRate += 0.05; - } - unspawnNotes = unspawnNotesCopy.copy(); - for (n in unspawnNotes) - { - n.active = true; - n.visible = true; - n.wasGoodHit = false; - n.canBeHit = false; - n.tooLate = false; - n.hitByOpponent = false; - n.spawned = false; - n.alpha = 1; - n.clipRect = null; - if (n.mustPress && !n.isSustainNote) - { - totalNotes += 1; - } else if (!n.mustPress && !n.isSustainNote) { - opponentNoteTotal += 1; - } - } - Conductor.songPosition = 0; - } - - public function infiniteLoop(?ignoreNoteOffset:Bool = false):Void - { - unspawnNotes = unspawnNotesCopy.copy(); - for (n in unspawnNotes) - { - n.active = true; - n.visible = true; - n.wasGoodHit = false; - n.canBeHit = false; - n.tooLate = false; - n.hitByOpponent = false; - n.spawned = false; - n.alpha = 1; - n.clipRect = null; - if (n.mustPress && !n.isSustainNote) - { - totalNotes += 1; - } else if (!n.mustPress && !n.isSustainNote) { - opponentNoteTotal += 1; - } - } - Conductor.songPosition = 0; - } - public function infiniteLoopLua(startPoint:Float = 0):Void - { - unspawnNotes = unspawnNotesCopy.copy(); - for (n in unspawnNotes) - { - if (n.strumTime >= Conductor.songPosition) - { - n.active = true; - n.visible = true; - n.wasGoodHit = false; - n.tooLate = false; - n.canBeHit = false; - n.hitByOpponent = false; - n.spawned = false; - n.alpha = 1; - n.clipRect = null; - if (n.mustPress && !n.isSustainNote) - { - totalNotes += 1; - } else if (!n.mustPress && !n.isSustainNote) { - opponentNoteTotal += 1; - } - } else { - n.active = false; - n.visible = false; - n.wasGoodHit = true; - n.tooLate = false; - n.canBeHit = false; - n.hitByOpponent = true; - n.spawned = true; - n.alpha = 0; - n.clipRect = null; - } - } - } - - - public var transitioning = false; - public var endedTheSong = false; - public function endSong():Void - { - //Should kill you if you tried to cheat - if(!startingSong) { - notes.forEach(function(daNote:Note) { - if(daNote.strumTime < songLength - Conductor.safeZoneOffset) { - health -= 0.05 * healthLoss; - } - }); - { - for (daNote in unspawnNotes) { - if(daNote.strumTime < songLength - Conductor.safeZoneOffset) { - health -= 0.05 * healthLoss; - } - } - } - if(doDeathCheck()) { - return; - } - } - if (!endedTheSong) - { - Conductor.songPosition = 0; //so that it doesnt skip the results screen - if (!ClientPrefs.resultsScreen) { - #if android - androidControls.visible = false; - #end - endedTheSong = true; - timeBarBG.visible = false; - timeBar.visible = false; - timeTxt.visible = false; - canPause = false; - endingSong = true; - camZooming = false; - inCutscene = false; - updateTime = false; - } - if (ClientPrefs.resultsScreen && !isStoryMode) { - new FlxTimer().start(0.02, function(tmr:FlxTimer) { - endedTheSong = true; - }); - persistentUpdate = false; - persistentDraw = true; - paused = true; - } - openSubState(new ResultsScreenSubState([marvs, sicks, goods, bads, shits], Std.int(songScore), songMisses, Highscore.floorDecimal(ratingPercent * 100, 2), - ratingName + (' [' + ratingFC + '] '))); - } - if (endedTheSong || !ClientPrefs.resultsScreen) - { - #if android - androidControls.visible = false; - #end - timeBarBG.visible = false; - timeBar.visible = false; - timeTxt.visible = false; - canPause = false; - endingSong = true; - camZooming = false; - inCutscene = false; - updateTime = false; - - deathCounter = 0; - seenCutscene = false; - - #if ACHIEVEMENTS_ALLOWED - if(achievementObj != null) { - return; - } else { - var achieve:String = checkForAchievement(['week1_nomiss', 'week2_nomiss', 'week3_nomiss', 'week4_nomiss', - 'week5_nomiss', 'week6_nomiss', 'week7_nomiss', 'ur_bad', - 'ur_good', 'hype', 'two_keys', 'toastie', 'debugger']); - var customAchieves:String = checkForAchievement(achievementWeeks); - - if(achieve != null || customAchieves != null) { - startAchievement(achieve); - return; - } - } - #end - - var ret:Dynamic = callOnLuas('onEndSong', [], false); - if(ret != FunkinLua.Function_Stop && !transitioning) { - if (SONG.validScore && !cpuControlled && !playerIsCheating && ClientPrefs.comboMultLimit <= 10 && ClientPrefs.safeFrames <= 10) - { - #if !switch - var percent:Float = ratingPercent; - if(Math.isNaN(percent)) percent = 0; - Highscore.saveScore(SONG.song, Std.int(songScore), storyDifficulty, percent); - #end - } - playbackRate = 1; - - if (chartingMode) - { - openChartEditor(); - return; - } - - if (isStoryMode) - { - campaignScore += songScore; - campaignMisses += songMisses; - - storyPlaylist.remove(storyPlaylist[0]); - - if (storyPlaylist.length <= 0) - { - WeekData.loadTheFirstEnabledMod(); - FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic)); - - cancelMusicFadeTween(); - if(FlxTransitionableState.skipNextTransIn) { - CustomFadeTransition.nextCamera = null; - } - if (ClientPrefs.resultsScreen) - openSubState(new ResultsScreenSubState([marvs, sicks, goods, bads, shits], Std.int(campaignScore), songMisses, - Highscore.floorDecimal(ratingPercent * 100, 2), ratingName + (' [' + ratingFC + '] '))); - else - MusicBeatState.switchState(new StoryMenuState()); - - // if () - if(!ClientPrefs.getGameplaySetting('practice', false) && !ClientPrefs.getGameplaySetting('botplay', false)) { - StoryMenuState.weekCompleted.set(WeekData.weeksList[storyWeek], true); - - if (SONG.validScore) - { - Highscore.saveWeekScore(WeekData.getWeekFileName(), Std.int(campaignScore), storyDifficulty); - } - - FlxG.save.data.weekCompleted = StoryMenuState.weekCompleted; - FlxG.save.flush(); - } - changedDifficulty = false; - } - else - { - var difficulty:String = CoolUtil.getDifficultyFilePath(); - - trace('LOADING NEXT SONG'); - trace(Paths.formatToSongPath(PlayState.storyPlaylist[0]) + difficulty); - - var winterHorrorlandNext = (Paths.formatToSongPath(SONG.song) == "eggnog"); - if (winterHorrorlandNext) - { - 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; - prevCamFollowPos = camFollowPos; - - PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0] + difficulty, PlayState.storyPlaylist[0]); - FlxG.sound.music.stop(); - - if(winterHorrorlandNext) { - new FlxTimer().start(1.5, function(tmr:FlxTimer) { - cancelMusicFadeTween(); - LoadingState.loadAndSwitchState(new PlayState()); - }); - } else { - cancelMusicFadeTween(); - LoadingState.loadAndSwitchState(new PlayState()); - } - } - } - else - { - trace('WENT BACK TO FREEPLAY??'); - WeekData.loadTheFirstEnabledMod(); - cancelMusicFadeTween(); - if(FlxTransitionableState.skipNextTransIn) { - CustomFadeTransition.nextCamera = null; - } - MusicBeatState.switchState(new FreeplayState()); - FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic)); - changedDifficulty = false; - } - } - transitioning = true; - } - } - - #if ACHIEVEMENTS_ALLOWED - var achievementObj:AchievementObject = null; - function startAchievement(achieve:String) { - achievementObj = new AchievementObject(achieve, camOther); - achievementObj.onFinish = achievementEnd; - add(achievementObj); - trace('Giving achievement ' + achieve); - } - function achievementEnd():Void - { - achievementObj = null; - if(endingSong && !inCutscene) { - endSong(); - } - } - #end - - public function KillNotes() { - while(notes.length > 0) { - var daNote:Note = notes.members[0]; - daNote.active = false; - daNote.visible = false; - - daNote.kill(); - notes.remove(daNote, true); - daNote.destroy(); - } - unspawnNotes = []; - eventNotes = []; - } - - public static function restartSong(noTrans:Bool = true) - { - PlayState.instance.paused = true; // For lua - if (ClientPrefs.songLoading) FlxG.sound.music.volume = 0; - if (ClientPrefs.songLoading) PlayState.instance.vocals.volume = 0; - - if(noTrans) - { - FlxTransitionableState.skipNextTransOut = true; - FlxG.resetState(); - } - else - { - MusicBeatState.resetState(); - } - } - - public var totalPlayed:Int = 0; - public var totalNotesHit:Float = 0.0; - public var totalNotes:Int = 0; - - public var showCombo:Bool = true; - public var showComboNum:Bool = true; - public var showRating:Bool = true; - - private function cachePopUpScore() - { - var pixelShitPart1:String = ''; - var pixelShitPart2:String = ''; - if (isPixelStage) - { - pixelShitPart1 = 'pixelUI/'; - pixelShitPart2 = '-pixel'; - } - if (ClientPrefs.ratingType == 'Doki Doki+') - { - pixelShitPart1 = 'dokistuff/'; - pixelShitPart2 = ''; - } - if (ClientPrefs.ratingType == 'Tails Gets Trolled V4') - { - pixelShitPart1 = 'tgtstuff/'; - pixelShitPart2 = ''; - } - if (ClientPrefs.ratingType == 'Kade Engine') - { - pixelShitPart1 = 'kadethings/'; - pixelShitPart2 = ''; - } - if (allSicks) - { - pixelShitPart1 = 'goldstuff/'; - pixelShitPart2 = ''; - } - if (allSicks || !allSicks && ClientPrefs.marvRateColor == 'Golden' && !ClientPrefs.noMarvJudge) - { - Paths.image(pixelShitPart1 + "marv" + pixelShitPart2); - } - if (!allSicks && ClientPrefs.marvRateColor == 'Rainbow' && !ClientPrefs.noMarvJudge) - { - Paths.image(pixelShitPart1 + "marv" + pixelShitPart2); - } - Paths.image(pixelShitPart1 + "sick" + pixelShitPart2); - Paths.image(pixelShitPart1 + "good" + pixelShitPart2); - Paths.image(pixelShitPart1 + "bad" + pixelShitPart2); - Paths.image(pixelShitPart1 + "shit" + pixelShitPart2); - Paths.image(pixelShitPart1 + "combo" + pixelShitPart2); - - for (i in 0...10) { - Paths.image(pixelShitPart1 + 'num' + i + pixelShitPart2); - } - } - - function doGhostAnim(char:String, animToPlay:String) - { - if (ClientPrefs.doubleGhost || ClientPrefs.charsAndBG) - { - var ghost:FlxSprite = dadGhost; - var player:Character = dad; - - switch(char.toLowerCase().trim()) - { - case 'bf': - ghost = bfGhost; - player = boyfriend; - case 'dad': - ghost = dadGhost; - player = dad; - case 'gf': - ghost = gfGhost; - player = gf; - } - - - ghost.frames = player.frames; - ghost.animation.copyFrom(player.animation); - ghost.x = player.x; - ghost.y = player.y; - ghost.animation.play(animToPlay, true); - ghost.offset.set(player.animOffsets.get(animToPlay)[0], player.animOffsets.get(animToPlay)[1]); - ghost.flipX = player.flipX; - ghost.flipY = player.flipY; - ghost.blend = HARDLIGHT; - ghost.alpha = 0.8; - ghost.visible = true; - - if (FlxG.camera.zoom < 1.35 && ClientPrefs.camZooms && camZooming && ClientPrefs.doubleGhostZoom) - { - FlxG.camera.zoom += 0.0075; - camHUD.zoom += 0.015; - } - - switch (char.toLowerCase().trim()) - { - case 'bf': - if (bfGhostTween != null) - bfGhostTween.cancel(); - ghost.color = FlxColor.fromRGB(boyfriend.healthColorArray[0] + 50, boyfriend.healthColorArray[1] + 50, boyfriend.healthColorArray[2] + 50); - bfGhostTween = FlxTween.tween(bfGhost, {alpha: 0}, 0.75, { - ease: FlxEase.linear, - onComplete: function(twn:FlxTween) - { - bfGhostTween = null; - } - }); - - case 'dad': - if (dadGhostTween != null) - dadGhostTween.cancel(); - ghost.color = FlxColor.fromRGB(dad.healthColorArray[0] + 50, dad.healthColorArray[1] + 50, dad.healthColorArray[2] + 50); - dadGhostTween = FlxTween.tween(dadGhost, {alpha: 0}, 0.75, { - ease: FlxEase.linear, - onComplete: function(twn:FlxTween) - { - dadGhostTween = null; - } - }); - case 'gf': - if (gfGhostTween != null) - gfGhostTween.cancel(); - ghost.color = FlxColor.fromRGB(gf.healthColorArray[0] + 50, gf.healthColorArray[1] + 50, gf.healthColorArray[2] + 50); - gfGhostTween = FlxTween.tween(gfGhost, {alpha: 0}, 0.75, { - ease: FlxEase.linear, - onComplete: function(twn:FlxTween) - { - gfGhostTween = null; - } - }); - } - } - } - - private function popUpScore(note:Note = null):Void - { - var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition + ClientPrefs.ratingOffset); - //trace(noteDiff, ' ' + Math.abs(note.strumTime - Conductor.songPosition)); - if (note != null && note.isSustainNote && ClientPrefs.holdNoteHits) noteDiff = 0; - 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.35; - // - if(ClientPrefs.scoreZoom && !ClientPrefs.hideScore && !cpuControlled) - { - if(scoreTxtTween != null) { - scoreTxtTween.cancel(); - } - scoreTxt.scale.x = 1.075; - scoreTxt.scale.y = 1.075; - scoreTxtTween = FlxTween.tween(scoreTxt.scale, {x: 1, y: 1}, 0.2, { - onComplete: function(twn:FlxTween) { - scoreTxtTween = null; - } - }); - } - - var rating:FlxSprite = new FlxSprite(); - var score:Float = 500 * polyphony; - - if (noteDiff > ClientPrefs.marvWindow && noteDiff < ClientPrefs.sickWindow && !ClientPrefs.noMarvJudge) maxScore -= 150 * Std.int(polyphony); //if you enable marvelous judges and hit a sick, lower the max score by 150 points. otherwise it won't make sense - - //tryna do MS based judgment due to popular demand - var daRating:Rating = Conductor.judgeNote(note, noteDiff / playbackRate); - - if (!ClientPrefs.complexAccuracy) totalNotesHit += daRating.ratingMod; - if (ClientPrefs.complexAccuracy) totalNotesHit += wife; - note.ratingMod = daRating.ratingMod; - if(!note.ratingDisabled) daRating.increase(); - note.rating = daRating.name; - score = daRating.score; - - if (goods > 0 || bads > 0 || shits > 0 || songMisses > 0 && ClientPrefs.goldSickSFC || !ClientPrefs.goldSickSFC) - { - // if it isn't a sick, and you had a sick combo, then it becomes not sick :( - if (allSicks) - allSicks = false; - - } - if (noteDiff > ClientPrefs.badWindow && ClientPrefs.shitGivesMiss && ClientPrefs.ratingIntensity == 'Normal') - { - noteMiss(note); - } - if (noteDiff > ClientPrefs.goodWindow && ClientPrefs.shitGivesMiss && ClientPrefs.ratingIntensity == 'Harsh') - { - noteMiss(note); - } - if (noteDiff > ClientPrefs.sickWindow && ClientPrefs.shitGivesMiss && ClientPrefs.ratingIntensity == 'Very Harsh') - { - noteMiss(note); - } - if (ClientPrefs.healthGainType == 'VS Impostor') { - if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) - { - health += note.hitHealth * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) - { - health += note.hitHealth * healthGain * polyphony; - } - if (note.isSustainNote) - { - health += note.hitHealth * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.sickWindow) - { - health += note.hitHealth * 0.5 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.goodWindow) - { - health += note.hitHealth * 0.25 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.badWindow) - { - health += note.hitHealth * 0.1 * healthGain * polyphony; - } - } - if (ClientPrefs.healthGainType == 'Leather Engine') { - if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) //you hit a marvelous!! - { - health += 0.012 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) - { - health += 0.012 * healthGain * polyphony; //you hit a sick! - } - if (noteDiff > ClientPrefs.sickWindow) //you hit a good rating - { - health += -0.008 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.goodWindow) //you hit a bad rating - { - health += -0.018 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.badWindow) //you hit a shit rating - { - health += -0.23; - } - } - if (ClientPrefs.healthGainType == 'Kade (1.4.2 to 1.6)') { - if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) - { - health += 0.1 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) - { - health += 0.1 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.sickWindow) - { - health += 0.04 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.goodWindow) - { - health -= 0.06 * healthLoss; - } - if (noteDiff > ClientPrefs.badWindow) - { - health -= 0.2 * healthLoss; - } - } - if (ClientPrefs.healthGainType == 'Doki Doki+') { - if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) - { - health += 0.077 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) - { - health += 0.077 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.sickWindow) - { - health += 0.04 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.goodWindow) - { - health -= 0.06 * healthLoss; - } - if (noteDiff > ClientPrefs.badWindow) - { - health -= 0.1 * healthLoss; - } - } - if (ClientPrefs.healthGainType == 'Kade (1.6+)') { - if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) - { - health += 0.017 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) - { - health += 0.017 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.sickWindow) - { - health += 0; - } - if (noteDiff > ClientPrefs.goodWindow) - { - health -= 0.03 * healthLoss; - } - if (noteDiff > ClientPrefs.badWindow) - { - health -= 0.06 * healthLoss; - } - } - if (ClientPrefs.healthGainType == 'Kade (1.2)') { - if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) - { - health += 0.023 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) - { - health += 0.023 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.sickWindow) - { - health += 0.004 * healthGain * polyphony; - } - if (noteDiff > ClientPrefs.goodWindow) - { - health -= 0; - } - if (noteDiff > ClientPrefs.badWindow) - { - health -= 0; - } - } - - if(daRating.noteSplash && !note.noteSplashDisabled) - { - spawnNoteSplashOnNote(false, note); - } - - if(!practiceMode) { - songScore += score * comboMultiplier * polyphony; - if(!note.ratingDisabled || cpuControlled && !ClientPrefs.lessBotLag && !note.ratingDisabled) - { - songHits++; - totalPlayed++; - if(!cpuControlled || cpuControlled && ClientPrefs.communityGameBot) { - RecalculateRating(false); - } - } - } - - var pixelShitPart1:String = ""; - var pixelShitPart2:String = ''; - - if (PlayState.isPixelStage) - { - pixelShitPart1 = 'pixelUI/'; - pixelShitPart2 = '-pixel'; - } - if (ClientPrefs.ratingType == 'Doki Doki+') - { - pixelShitPart1 = 'dokistuff/'; - pixelShitPart2 = ''; - } - if (ClientPrefs.ratingType == 'Tails Gets Trolled V4') - { - pixelShitPart1 = 'tgtstuff/'; - pixelShitPart2 = ''; - } - if (ClientPrefs.ratingType == 'Kade Engine') - { - pixelShitPart1 = 'kadethings/'; - pixelShitPart2 = ''; - } - if (allSicks && ClientPrefs.marvRateColor == 'Golden' && noteDiff < ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && !ClientPrefs.noMarvJudge) - { - pixelShitPart1 = 'goldstuff/'; - pixelShitPart2 = ''; - } - if (!allSicks && ClientPrefs.marvRateColor == 'Golden' && noteDiff < ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && !ClientPrefs.noMarvJudge) - { - pixelShitPart1 = 'goldstuff/'; - pixelShitPart2 = ''; - } - if (!allSicks && ClientPrefs.marvRateColor == 'Rainbow' && noteDiff < ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && !ClientPrefs.noMarvJudge) - { - pixelShitPart1 = ''; - pixelShitPart2 = ''; - } - if (ClientPrefs.ratesAndCombo) { - rating.loadGraphic(Paths.image(pixelShitPart1 + daRating.image + pixelShitPart2)); - rating.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); - rating.screenCenter(); - rating.x = coolText.x - 40; - rating.y -= 60; - rating.acceleration.y = 550 * playbackRate * playbackRate; - rating.velocity.y -= FlxG.random.int(140, 175) * playbackRate; - rating.velocity.x -= FlxG.random.int(0, 10) * playbackRate; - rating.visible = (!ClientPrefs.hideHud && showRating); - rating.x += ClientPrefs.comboOffset[0]; - rating.y -= ClientPrefs.comboOffset[1]; -if (!allSicks && ClientPrefs.colorRatingFC && marvs > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.noMarvJudge) - { - rating.color = judgeColours.get('marv'); - } -if (!allSicks && ClientPrefs.colorRatingFC && sicks > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.marvRateColor != 'Golden' && !ClientPrefs.noMarvJudge) - { - rating.color = judgeColours.get('sick'); - } -if (!allSicks && ClientPrefs.colorRatingFC && goods > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') - { - rating.color = judgeColours.get('good'); - } -if (!allSicks && ClientPrefs.colorRatingFC && bads > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') - { - rating.color = judgeColours.get('bad'); - } -if (!allSicks && ClientPrefs.colorRatingFC && shits > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') - { - rating.color = judgeColours.get('shit'); - } -if (!allSicks && ClientPrefs.colorRatingHit && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.noMarvJudge) - { - rating.color = judgeColours.get('marv'); - } -if (!allSicks && ClientPrefs.colorRatingHit && noteDiff > ClientPrefs.marvWindow && noteDiff < ClientPrefs.sickWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.marvRateColor != 'Golden' && !ClientPrefs.noMarvJudge) - { - rating.color = judgeColours.get('sick'); - } -if (!allSicks && ClientPrefs.colorRatingHit && noteDiff > ClientPrefs.sickWindow && noteDiff < ClientPrefs.goodWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') - { - rating.color = judgeColours.get('good'); - } -if (!allSicks && ClientPrefs.colorRatingHit && bads > 0 && noteDiff > ClientPrefs.goodWindow && noteDiff < ClientPrefs.badWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') - { - rating.color = judgeColours.get('bad'); - } -if (!allSicks && ClientPrefs.colorRatingHit && noteDiff > ClientPrefs.badWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') - { - rating.color = judgeColours.get('shit'); - } - insert(members.indexOf(strumLineNotes), rating); - - if (ClientPrefs.showMS && !ClientPrefs.hideHud) { - FlxTween.cancelTweensOf(msTxt); - FlxTween.cancelTweensOf(msTxt.scale); - var msTiming:Float = note.strumTime - Conductor.songPosition + ClientPrefs.ratingOffset; - var time = (Conductor.stepCrochet * 0.001); //ms popup shit - msTxt.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); - msTxt.visible = true; - msTxt.screenCenter(); - msTxt.x = (ClientPrefs.comboPopup ? coolText.x + 280 : coolText.x + 80); - msTxt.alpha = 1; - msTxt.text = FlxMath.roundDecimal(-msTiming, 3) + " MS"; - if (cpuControlled && !ClientPrefs.communityGameBot) msTxt.text = "0 MS (Bot)"; - msTxt.x += ClientPrefs.comboOffset[0]; - msTxt.y -= ClientPrefs.comboOffset[1]; - if (combo >= 1000000) msTxt.x += 30; - if (combo >= 100000) msTxt.x += 30; - if (combo >= 10000) msTxt.x += 30; - FlxTween.tween(msTxt, - {y: msTxt.y + 8}, - 0.1 / playbackRate, - {onComplete: function(_){ - - FlxTween.tween(msTxt, {alpha: 0}, time, { - // ease: FlxEase.circOut, - onComplete: function(_){msTxt.visible = false;}, - startDelay: time * 5 / playbackRate - }); - } - }); - if (noteDiff <= ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) msTxt.color = FlxColor.YELLOW; - if (noteDiff <= ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) msTxt.color = FlxColor.CYAN; - if (noteDiff <= ClientPrefs.sickWindow && noteDiff >= ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) msTxt.color = FlxColor.CYAN; - if (noteDiff >= ClientPrefs.sickWindow) msTxt.color = FlxColor.LIME; - if (noteDiff >= ClientPrefs.goodWindow) msTxt.color = FlxColor.ORANGE; - if (noteDiff >= ClientPrefs.badWindow) msTxt.color = FlxColor.RED; - if (!msTxt.visible) msTxt.color = FlxColor.WHITE; - } - var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); - comboSpr.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); - comboSpr.screenCenter(); - comboSpr.x = coolText.x; - comboSpr.acceleration.y = FlxG.random.int(200, 300) * playbackRate * playbackRate; - comboSpr.velocity.y -= FlxG.random.int(140, 160) * playbackRate; - comboSpr.visible = (!ClientPrefs.hideHud && showCombo); - comboSpr.x += ClientPrefs.comboOffset[0]; - comboSpr.y -= ClientPrefs.comboOffset[1]; - comboSpr.y += 60; - comboSpr.color = rating.color; - comboSpr.velocity.x += FlxG.random.int(1, 10) * playbackRate; - if (ClientPrefs.comboPopup && !cpuControlled) - { - insert(members.indexOf(strumLineNotes), comboSpr); - } - if (!ClientPrefs.comboStacking) - { - if (lastCombo != null) lastCombo.kill(); - lastCombo = comboSpr; - } - - if (!ClientPrefs.comboStacking) - { - if (lastRating != null) lastRating.kill(); - lastRating = rating; - } - - if (!PlayState.isPixelStage) - { - rating.setGraphicSize(Std.int(rating.width * 0.7)); - rating.antialiasing = ClientPrefs.globalAntialiasing; - comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7)); - comboSpr.antialiasing = ClientPrefs.globalAntialiasing; - } - else - { - rating.setGraphicSize(Std.int(rating.width * daPixelZoom * 0.85)); - comboSpr.setGraphicSize(Std.int(comboSpr.width * daPixelZoom * 0.85)); - } - - comboSpr.updateHitbox(); - rating.updateHitbox(); - - var seperatedScore:Array = []; - //much faster combo popup stuff - for (i in 0...Std.string(combo).length) { - seperatedScore.push(Std.parseInt(Std.string(combo).split("")[i])); - } - - - - var daLoop:Int = 0; - var xThing:Float = 0; - if (ClientPrefs.comboPopup && !cpuControlled) - { - insert(members.indexOf(strumLineNotes), comboSpr); - } - if (!ClientPrefs.comboStacking) - { - if (lastCombo != null) lastCombo.kill(); - lastCombo = comboSpr; - } - if (lastScore != null) - { - while (lastScore.length > 0) - { - lastScore[0].kill(); - lastScore.remove(lastScore[0]); - } - } - for (i in seperatedScore) - { - var numScore:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2)); - numScore.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); - numScore.screenCenter(); - numScore.x = coolText.x + (43 * daLoop) - 90; - numScore.y += 80; - - numScore.x += ClientPrefs.comboOffset[2]; - numScore.y -= ClientPrefs.comboOffset[3]; -if (ClientPrefs.colorRatingHit && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && noteDiff >= ClientPrefs.marvWindow) numScore.color = rating.color; -if (!allSicks && ClientPrefs.colorRatingFC && marvs > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') - { - numScore.color = tgtJudgeColours.get('marv'); - } -if (!allSicks && ClientPrefs.colorRatingFC && sicks > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') - { - numScore.color = tgtJudgeColours.get('sick'); - } -if (!allSicks && ClientPrefs.colorRatingFC && goods > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') - { - numScore.color = tgtJudgeColours.get('good'); - } -if (!allSicks && ClientPrefs.colorRatingFC && bads > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') - { - numScore.color = tgtJudgeColours.get('bad'); - } -if (!allSicks && ClientPrefs.colorRatingFC && shits > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') - { - numScore.color = tgtJudgeColours.get('shit'); - } -if (!allSicks && ClientPrefs.colorRatingFC && songMisses > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') - { - numScore.color = FlxColor.WHITE; - } - - if (!ClientPrefs.comboStacking) - lastScore.push(numScore); - - if (!PlayState.isPixelStage) - { - numScore.antialiasing = ClientPrefs.globalAntialiasing; - 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) * playbackRate * playbackRate; - numScore.velocity.y -= FlxG.random.int(140, 160) * playbackRate; - numScore.velocity.x = FlxG.random.float(-5, 5) * playbackRate; - numScore.visible = !ClientPrefs.hideHud; - - //if (combo >= 10 || combo == 0) - if(showComboNum) - insert(members.indexOf(strumLineNotes), numScore); - - FlxTween.tween(numScore, {alpha: 0}, 0.2 / playbackRate, { - onComplete: function(tween:FlxTween) - { - numScore.destroy(); - }, - startDelay: Conductor.crochet * 0.002 / playbackRate - }); - - daLoop++; - if(numScore.x > xThing) xThing = numScore.x; - } - comboSpr.x = xThing + 50; - /* - trace(combo); - trace(seperatedScore); - */ - - coolText.text = Std.string(seperatedScore); - // add(coolText); - - FlxTween.tween(rating, {alpha: 0}, 0.2 / playbackRate, { - startDelay: Conductor.crochet * 0.001 / playbackRate - }); - - FlxTween.tween(comboSpr, {alpha: 0}, 0.2 / playbackRate, { - onComplete: function(tween:FlxTween) - { - coolText.destroy(); - comboSpr.destroy(); - - rating.destroy(); - }, - startDelay: Conductor.crochet * 0.002 / playbackRate - }); - } - } - - public var strumsBlocked:Array = []; - private function onKeyPress(event:KeyboardEvent):Void - { - var eventKey:FlxKey = event.keyCode; - var key:Int = getKeyFromEvent(eventKey); - //trace('Pressed: ' + eventKey); - - if (!cpuControlled && startedCountdown && !paused && key > -1 && !softlocked && (FlxG.keys.checkStatus(eventKey, JUST_PRESSED) || ClientPrefs.controllerMode)) - { - if(!boyfriend.stunned && generatedMusic && !endingSong) - { - //more accurate hit time for the ratings? - var lastTime:Float = Conductor.songPosition; - if (ClientPrefs.songLoading) Conductor.songPosition = FlxG.sound.music.time; - - var canMiss:Bool = !ClientPrefs.ghostTapping; - - // heavily based on my own code LOL if it aint broke dont fix it - var pressNotes:Array = []; - //var notesDatas:Array = []; - var notesStopped:Bool = false; - - var hittableSpam = []; - - var sortedNotesList:Array = []; - notes.forEachAlive(function(daNote:Note) - { - if (strumsBlocked[daNote.noteData] != true && daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit && !daNote.isSustainNote && !daNote.blockHit) - { - if(daNote.noteData == key) - { - sortedNotesList.push(daNote); - //notesDatas.push(daNote.noteData); - } - canMiss = true; - } - }); - sortedNotesList.sort(sortHitNotes); - - if (sortedNotesList.length > 0) { - for (epicNote in sortedNotesList) - { - for (doubleNote in pressNotes) { - if (Math.abs(doubleNote.strumTime - epicNote.strumTime) < 1) { - if (shouldKillNotes) - { - doubleNote.kill(); - } - notes.remove(doubleNote, true); - if (shouldKillNotes) - { - doubleNote.destroy(); - } - } else - notesStopped = true; - } - - // eee jack detection before was not super good - if (!notesStopped) { - goodNoteHit(epicNote); - pressNotes.push(epicNote); - } - if (sortedNotesList.length > 2 && ClientPrefs.ezSpam) //literally all you need to allow you to spam though impossiblely hard jacks - { - var notesThatCanBeHit = sortedNotesList.length; - for (i in 1...Std.int(notesThatCanBeHit)) //i may consider making this hit half the notes instead - { - goodNoteHit(sortedNotesList[i]); - } - - } - } - } - else { - callOnLuas('onGhostTap', [key]); - if (!opponentChart && ClientPrefs.ghostTapAnim && ClientPrefs.charsAndBG) - { - boyfriend.playAnim(singAnimations[Std.int(Math.abs(key))], true); - if (ClientPrefs.cameraPanning) camPanRoutine(singAnimations[Std.int(Math.abs(key))], 'bf'); - boyfriend.holdTimer = 0; - } - if (opponentChart && ClientPrefs.ghostTapAnim && ClientPrefs.charsAndBG) - { - dad.playAnim(singAnimations[Std.int(Math.abs(key))], true); - if (ClientPrefs.cameraPanning) camPanRoutine(singAnimations[Std.int(Math.abs(key))], 'dad'); - dad.holdTimer = 0; - } - if (canMiss) { - noteMissPress(key); - } - } - - // I dunno what you need this for but here you go - // - Shubs - - // Shubs, this is for the "Just the Two of Us" achievement lol - // - Shadow Mario - keysPressed[key] = true; - - //more accurate hit time for the ratings? part 2 (Now that the calculations are done, go back to the time it was before for not causing a note stutter) - Conductor.songPosition = lastTime; - } - - var spr:StrumNote = playerStrums.members[key]; - if(strumsBlocked[key] != true && spr != null && spr.animation.curAnim.name != 'confirm') - { - spr.playAnim('pressed'); - spr.resetAnim = 0; - } - callOnLuas('onKeyPress', [key]); - } - //trace('pressed: ' + controlArray); - } - - function sortHitNotes(a:Note, b:Note):Int - { - if (a.lowPriority && !b.lowPriority) - return 1; - else if (!a.lowPriority && b.lowPriority) - return -1; - - return FlxSort.byValues(FlxSort.ASCENDING, a.strumTime, b.strumTime); - } - - private function onKeyRelease(event:KeyboardEvent):Void - { - var eventKey:FlxKey = event.keyCode; - var key:Int = getKeyFromEvent(eventKey); - if(!cpuControlled && startedCountdown && !paused && key > -1) - { - var spr:StrumNote = playerStrums.members[key]; - if(spr != null) - { - spr.playAnim('static'); - spr.resetAnim = 0; - } - callOnLuas('onKeyRelease', [key]); - } - //trace('released: ' + controlArray); - } - - private function getKeyFromEvent(key:FlxKey):Int - { - if(key != NONE) - { - for (i in 0...keysArray.length) - { - for (j in 0...keysArray[i].length) - { - if(key == keysArray[i][j]) - { - return i; - } - } - } - } - return -1; - } - - // Hold notes - private function keyShit():Void - { - // HOLDING - var parsedHoldArray:Array = parseKeys(); - - // TO DO: Find a better way to handle controller inputs, this should work for now - if(ClientPrefs.controllerMode) - { - var parsedArray:Array = parseKeys('_P'); - if(parsedArray.contains(true)) - { - for (i in 0...parsedArray.length) - { - if(parsedArray[i] && strumsBlocked[i] != true) - onKeyPress(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, true, -1, keysArray[i][0])); - } - } - } - - // FlxG.watch.addQuick('asdfa', upP); - var char:Character = boyfriend; - if (opponentChart) char = dad; - if (startedCountdown && !char.stunned && generatedMusic) - { - // rewritten inputs??? - notes.forEachAlive(function(daNote:Note) - { - // hold note functions - if (strumsBlocked[daNote.noteData] != true && daNote.isSustainNote && parsedHoldArray[daNote.noteData] && daNote.canBeHit - && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit && !daNote.blockHit) { - goodNoteHit(daNote); - } - }); - - if(ClientPrefs.charsAndBG && FlxG.keys.anyJustPressed(tauntKey) && !char.animation.curAnim.name.endsWith('miss') && char.specialAnim == false && ClientPrefs.spaceVPose){ - char.playAnim('hey', true); - char.specialAnim = true; - char.heyTimer = 0.59; - FlxG.sound.play(Paths.sound('hey')); - trace("HEY!!"); - } - - if (parsedHoldArray.contains(true) && !endingSong) { - #if ACHIEVEMENTS_ALLOWED - var achieve:String = checkForAchievement(['oversinging']); - if (achieve != null) { - startAchievement(achieve); - } - #end - } - else if (ClientPrefs.charsAndBG && boyfriend.animation.curAnim != null && boyfriend.holdTimer > Conductor.stepCrochet * (0.0011 / playbackRate) * boyfriend.singDuration && boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss')) - { - boyfriend.dance(); - //boyfriend.animation.curAnim.finish(); - } - else if (ClientPrefs.charsAndBG && dad.holdTimer > Conductor.stepCrochet * (0.0011 / playbackRate) * dad.singDuration - && dad.animation.curAnim.name.startsWith('sing') && !dad.animation.curAnim.name.endsWith('miss')) { - dad.dance(); - } - } - - // TO DO: Find a better way to handle controller inputs, this should work for now - if(ClientPrefs.controllerMode || strumsBlocked.contains(true)) - { - var parsedArray:Array = parseKeys('_R'); - if(parsedArray.contains(true)) - { - for (i in 0...parsedArray.length) - { - if(parsedArray[i] || strumsBlocked[i] == true) - onKeyRelease(new KeyboardEvent(KeyboardEvent.KEY_UP, true, true, -1, keysArray[i][0])); - } - } - } - } - - private function parseKeys(?suffix:String = ''):Array - { - var ret:Array = []; - for (i in 0...controlArray.length) - { - ret[i] = Reflect.getProperty(controls, controlArray[i] + suffix); - } - return ret; - } - - function noteMiss(daNote:Note):Void { //You didn't hit the key and let it go offscreen, also used by Hurt Notes - //Dupe note remove - notes.forEachAlive(function(note:Note) { - if (daNote != note && daNote.mustPress && daNote.noteData == note.noteData && daNote.isSustainNote == note.isSustainNote && Math.abs(daNote.strumTime - note.strumTime) < 1) { - if (shouldKillNotes) - { - note.kill(); - } - notes.remove(note, true); - if (shouldKillNotes) - { - note.destroy(); - } - } - }); - combo = 0; - comboMultiplier = 1; // Reset to 1 on a miss - if (ClientPrefs.healthGainType == 'Psych Engine') { - health -= daNote.missHealth * healthLoss; - } - if (ClientPrefs.healthGainType == 'Kade (1.2)') { - health -= daNote.missHealth * healthLoss; - } - if (ClientPrefs.healthGainType == 'Leather Engine') { - health -= 0.07 * healthLoss; - } - if (ClientPrefs.healthGainType == 'Kade (1.4.2 to 1.6)') { - health -= 0.075 * healthLoss; - } - if (ClientPrefs.healthGainType == 'Kade (1.6+)') { - health -= 0.1 * healthLoss; - } - if (ClientPrefs.healthGainType == 'Doki Doki+') { - health -= 0.04 * healthLoss; - } - if (ClientPrefs.healthGainType == 'VS Impostor') { - missCombo += 1; - health -= daNote.missHealth * missCombo; - } - - - if(instakillOnMiss) - { - vocals.volume = 0; - doDeathCheck(true); - } - - //For testing purposes - //trace(daNote.missHealth); - songMisses++; - vocals.volume = 0; - if(!practiceMode) songScore -= 10 * Std.int(polyphony); - - totalPlayed++; - RecalculateRating(true); - - var char:Character = boyfriend; - if(daNote.gfNote) { - char = gf; - } - if (opponentChart) char = dad; - - if(char != null && !daNote.noMissAnimation && char.hasMissAnimations && ClientPrefs.charsAndBG) - { - var animToPlay:String = singAnimations[Std.int(Math.abs(daNote.noteData))] + 'miss' + daNote.animSuffix; - char.playAnim(animToPlay, true); - } - - callOnLuas('noteMiss', [notes.members.indexOf(daNote), daNote.noteData, daNote.noteType, daNote.isSustainNote]); - } - - function noteMissPress(direction:Int = 1):Void //You pressed a key when there was no notes to press for this key - { - if(ClientPrefs.ghostTapping) return; //fuck it - - if (!boyfriend.stunned) - { - - health -= 0.05 * healthLoss; - if(instakillOnMiss) - { - vocals.volume = 0; - doDeathCheck(true); - } - - if (combo > 5 && gf != null && gf.animOffsets.exists('sad')) - { - gf.playAnim('sad'); - } - combo = 0; - comboMultiplier = 1; // Reset to 1 on a miss - - if(!practiceMode) songScore -= 10; - if(!endingSong) { - songMisses++; - } - totalPlayed++; - RecalculateRating(true); - - FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); - // FlxG.sound.play(Paths.sound('missnote1'), 1, false); - // FlxG.log.add('played imss note'); - - /*boyfriend.stunned = true; - - // get stunned for 1/60 of a second, makes you able to - new FlxTimer().start(1 / 60, function(tmr:FlxTimer) - { - boyfriend.stunned = false; - });*/ - - var char:Character = boyfriend; - if (opponentChart) char = dad; - if(char.hasMissAnimations) { - char.playAnim(singAnimations[Std.int(Math.abs(direction))] + 'miss', true); - } - vocals.volume = 0; - } - callOnLuas('noteMissPress', [direction]); - } - - var hitsound:FlxSound; - var hitsound2:FlxSound; - var hitsound3:FlxSound; - var hitsound4:FlxSound; - var hitsound5:FlxSound; - var hitsound6:FlxSound; - var hitsound7:FlxSound; - var hitsound8:FlxSound; - var hitsound9:FlxSound; - var hitsound10:FlxSound; - var hitsound11:FlxSound; - - function goodNoteHit(note:Note):Void - { - if (opponentChart) { - if (Paths.formatToSongPath(SONG.song) != 'tutorial' && !camZooming) - camZooming = true; - } - if (!note.wasGoodHit) - { - if(cpuControlled && (note.ignoreNote || note.hitCausesMiss)) return; - - if (ClientPrefs.hitsoundVolume > 0 && !note.hitsoundDisabled) - { - if (hitSoundString != 'Randomized') - { - hitsound.play(true); - hitsound.pitch = playbackRate; - } - if (hitSoundString == 'Randomized') - { - hitsound.pitch = playbackRate; - hitsound2.pitch = playbackRate; - hitsound3.pitch = playbackRate; - hitsound4.pitch = playbackRate; - hitsound5.pitch = playbackRate; - hitsound6.pitch = playbackRate; - hitsound7.pitch = playbackRate; - hitsound8.pitch = playbackRate; - hitsound9.pitch = playbackRate; - hitsound10.pitch = playbackRate; - hitsound11.pitch = playbackRate; - } - if (hitSoundString == 'vine boom') - { - SPUNCHBOB = new FlxSprite().loadGraphic(Paths.image('sadsponge')); - SPUNCHBOB.antialiasing = ClientPrefs.globalAntialiasing; - SPUNCHBOB.scrollFactor.set(); - SPUNCHBOB.setGraphicSize(Std.int(SPUNCHBOB.width / FlxG.camera.zoom)); - SPUNCHBOB.updateHitbox(); - SPUNCHBOB.screenCenter(); - SPUNCHBOB.alpha = 1; - SPUNCHBOB.cameras = [camGame]; - add(SPUNCHBOB); - FlxTween.tween(SPUNCHBOB, {alpha: 0}, 1 / (SONG.bpm/100) / playbackRate, { - onComplete: function(tween:FlxTween) - { - SPUNCHBOB.destroy(); - } - }); - } - if (hitSoundString == "i'm spongebob!") - { - SPUNCHBOB = new FlxSprite().loadGraphic(Paths.image('itspongebob')); - SPUNCHBOB.antialiasing = ClientPrefs.globalAntialiasing; - SPUNCHBOB.scrollFactor.set(); - SPUNCHBOB.setGraphicSize(Std.int(SPUNCHBOB.width / FlxG.camera.zoom)); - SPUNCHBOB.updateHitbox(); - SPUNCHBOB.screenCenter(); - SPUNCHBOB.alpha = 1; - SPUNCHBOB.cameras = [camGame]; - add(SPUNCHBOB); - FlxTween.tween(SPUNCHBOB, {alpha: 0}, 1 / (SONG.bpm/100) / playbackRate, { - onComplete: function(tween:FlxTween) - { - SPUNCHBOB.destroy(); - } - }); - } - if (ClientPrefs.hitsoundType == 'Randomized') { - var randomHitSoundType:Int = FlxG.random.int(1, 11); - switch (randomHitSoundType) - { - case 1: - hitsound.play(true); - hitsound.pitch = playbackRate; - case 2: - hitsound2.play(true); - hitsound2.pitch = playbackRate; - case 3: - hitsound3.play(true); - hitsound3.pitch = playbackRate; - case 4: - hitsound4.play(true); - hitsound4.pitch = playbackRate; - case 5: - hitsound5.play(true); - hitsound5.pitch = playbackRate; - case 6: - hitsound6.play(true); - hitsound6.pitch = playbackRate; - case 7: - hitsound7.play(true); - hitsound7.pitch = playbackRate; - case 8: - hitsound8.play(true); - hitsound8.pitch = playbackRate; - { - SPUNCHBOB = new FlxSprite().loadGraphic(Paths.image('sadsponge')); - SPUNCHBOB.antialiasing = ClientPrefs.globalAntialiasing; - SPUNCHBOB.scrollFactor.set(); - SPUNCHBOB.setGraphicSize(Std.int(SPUNCHBOB.width / FlxG.camera.zoom)); - SPUNCHBOB.updateHitbox(); - SPUNCHBOB.screenCenter(); - SPUNCHBOB.alpha = 1; - SPUNCHBOB.cameras = [camGame]; - add(SPUNCHBOB); - FlxTween.tween(SPUNCHBOB, {alpha: 0}, 1 / (SONG.bpm/100) / playbackRate, { - onComplete: function(tween:FlxTween) - { - SPUNCHBOB.destroy(); - } - }); - } - case 9: - hitsound9.play(true); - hitsound9.pitch = playbackRate; - case 10: - hitsound10.play(true); - hitsound10.pitch = playbackRate; - case 11: - hitsound11.play(true); - hitsound11.pitch = playbackRate; - { - SPUNCHBOB = new FlxSprite().loadGraphic(Paths.image('itspongebob')); - SPUNCHBOB.antialiasing = ClientPrefs.globalAntialiasing; - SPUNCHBOB.scrollFactor.set(); - SPUNCHBOB.setGraphicSize(Std.int(SPUNCHBOB.width / FlxG.camera.zoom)); - SPUNCHBOB.updateHitbox(); - SPUNCHBOB.screenCenter(); - SPUNCHBOB.alpha = 1; - SPUNCHBOB.cameras = [camGame]; - add(SPUNCHBOB); - FlxTween.tween(SPUNCHBOB, {alpha: 0}, 1 / (SONG.bpm/100) / playbackRate, { - onComplete: function(tween:FlxTween) - { - SPUNCHBOB.destroy(); - } - }); - } - } - } - } - - if(note.hitCausesMiss) { - noteMiss(note); - if(!note.noteSplashDisabled && !note.isSustainNote) { - spawnNoteSplashOnNote(false, note); - } - - if(!note.noMissAnimation) - { - switch(note.noteType) { - case 'Hurt Note': //Hurt note - if(boyfriend.animation.getByName('hurt') != null) { - boyfriend.playAnim('hurt', true); - boyfriend.specialAnim = true; - } - } - } - - note.wasGoodHit = true; - if (!note.isSustainNote) - { - if (shouldKillNotes) - { - note.kill(); - } - if (ClientPrefs.showNotes) notes.remove(note, true); - if (shouldKillNotes) - { - note.destroy(); - } - } - return; - } - if (ClientPrefs.comboScoreEffect && ClientPrefs.comboMultiType == 'Voiid Chronicles') - { - comboMultiplier = Math.fceil((combo+1)/10); - } - - if (!note.isSustainNote && !cpuControlled && !ClientPrefs.lessBotLag || !note.isSustainNote && cpuControlled && ClientPrefs.communityGameBot) - { - combo += 1 * polyphony; - totalNotesPlayed += 1 * polyphony; - missCombo = 0; - if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well - notesHitArray.push(1 * polyphony); - notesHitDateArray.push(Date.now()); - } - popUpScore(note); - } - if (note.isSustainNote && !cpuControlled && ClientPrefs.holdNoteHits) - { - combo += 1 * polyphony; - totalNotesPlayed += 1 * polyphony; - missCombo = 0; - popUpScore(note); - } - if (note.isSustainNote && cpuControlled && ClientPrefs.communityGameBot && ClientPrefs.holdNoteHits && !ClientPrefs.lessBotLag) - { - combo += 1 * polyphony; - totalNotesPlayed += 1 * polyphony; - missCombo = 0; - popUpScore(note); - } - if (note.isSustainNote && cpuControlled && ClientPrefs.holdNoteHits && ClientPrefs.lessBotLag) - { - combo += 1 * polyphony; - totalNotesPlayed += 1 * polyphony; - if (!ClientPrefs.noMarvJudge) - { - songScore += 500 * comboMultiplier * polyphony; - } - else if (ClientPrefs.noMarvJudge) - { - songScore += 350 * comboMultiplier * polyphony; - } - missCombo = 0; - } - if (!note.isSustainNote && cpuControlled && ClientPrefs.lessBotLag && !ClientPrefs.communityGameBot) - { - if (!ClientPrefs.noMarvJudge) - { - songScore += 500 * comboMultiplier * polyphony; - } - else if (ClientPrefs.noMarvJudge) - { - songScore += 350 * comboMultiplier * polyphony; - } - combo += 1 * polyphony; - totalNotesPlayed += 1 * polyphony; - if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well - notesHitArray.push(1 * polyphony); - notesHitDateArray.push(Date.now()); - } - if(!note.noteSplashDisabled && !note.isSustainNote) { - spawnNoteSplashOnNote(false, note); - } - } - if (!note.isSustainNote && cpuControlled && !ClientPrefs.lessBotLag && !ClientPrefs.communityGameBot) - { - combo += 1 * polyphony; - totalNotesPlayed += 1 * polyphony; - //updateScore(); the update function handles updating this, so why make it update more - //updateRatingCounter(); the update function handles updating this, so why make it update more - missCombo = 0; - if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well - notesHitArray.push(1 * polyphony); - notesHitDateArray.push(Date.now()); - } - popUpScore(note); - } - if (!note.isSustainNote && !cpuControlled && ClientPrefs.lessBotLag && !ClientPrefs.communityGameBot) - { - combo += 1 * polyphony; - totalNotesPlayed += 1 * polyphony; - //updateScore(); the update function handles updating this, so why make it update more - //updateRatingCounter(); the update function handles updating this, so why make it update more - missCombo = 0; - if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well - notesHitArray.push(1 * polyphony); - notesHitDateArray.push(Date.now()); - } - var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition + ClientPrefs.ratingOffset); - var daRating:Rating = Conductor.judgeNote(note, noteDiff / playbackRate); - - totalNotesHit += daRating.ratingMod; - //if (ClientPrefs.complexAccuracy) totalNotesHit += wife; whoopsies - note.ratingMod = daRating.ratingMod; - if(!note.ratingDisabled) daRating.increase(); - note.rating = daRating.name; - songScore += daRating.score * comboMultiplier * polyphony; - totalPlayed++; - if(daRating.noteSplash && !note.noteSplashDisabled) - { - spawnNoteSplashOnNote(false, note); - } - RecalculateRating(); - } - if (note.isSustainNote && cpuControlled && !ClientPrefs.lessBotLag && !ClientPrefs.communityGameBot && ClientPrefs.holdNoteHits) - { - combo += 1 * polyphony; - totalNotesPlayed += 1 * polyphony; - //updateScore(); the update function handles updating this, so why make it update more - //updateRatingCounter(); the update function handles updating this, so why make it update more - missCombo = 0; - if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well - notesHitArray.push(1 * polyphony); - notesHitDateArray.push(Date.now()); - } - popUpScore(note); - } - if (ClientPrefs.healthGainType == 'Psych Engine') { - health += note.hitHealth * healthGain * polyphony; - } - if (ClientPrefs.healthGainType == 'Leather Engine') { - health += note.hitHealth * healthGain * polyphony; - } - if (ClientPrefs.healthGainType == 'Kade (1.2)') { - health += note.hitHealth * healthGain * polyphony; - } - if (ClientPrefs.healthGainType == 'Kade (1.6+)') { - health += note.hitHealth * healthGain * polyphony; - } - if (ClientPrefs.healthGainType == 'Doki Doki+') { - health += note.hitHealth * healthGain * polyphony; - } - if (ClientPrefs.healthGainType == 'VS Impostor') { - health += note.hitHealth * healthGain * polyphony; - } - if(!note.noAnimation && ClientPrefs.charsAndBG) { - var animToPlay:String = singAnimations[Std.int(Math.abs(note.noteData))]; - - var char:Character = boyfriend; - if(opponentChart) char = dad; - if(note.gfNote) - { - if(gf != null) - { - if (!ClientPrefs.doubleGhost) { - gf.playAnim(animToPlay + note.animSuffix, true); - } - gf.holdTimer = 0; - if (ClientPrefs.doubleGhost) - { - if (!note.isSustainNote && noteRows[note.mustPress?0:1][note.row].length > 1) - { - // potentially have jump anims? - var chord = noteRows[note.mustPress?0:1][note.row]; - var animNote = chord[0]; - var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; - if (gf.mostRecentRow != note.row) - { - gf.playAnim(realAnim, true); - } - - // if (daNote != animNote) - // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); - - - gf.mostRecentRow = note.row; - // dad.angle += 15; lmaooooo - doGhostAnim('gf', animToPlay); - gfGhost.color = FlxColor.fromRGB(gf.healthColorArray[0] + 50, gf.healthColorArray[1] + 50, gf.healthColorArray[2] + 50); - gfGhostTween = FlxTween.tween(gfGhost, {alpha: 0}, 0.75, { - ease: FlxEase.linear, - onComplete: function(twn:FlxTween) - { - gfGhostTween = null; - } - }); - } - else{ - gf.playAnim(animToPlay + note.animSuffix, true); - // dad.angle = 0; - } - } - } - } - if (!opponentChart && !note.gfNote && ClientPrefs.charsAndBG) - { - if (!ClientPrefs.doubleGhost) { - boyfriend.playAnim(animToPlay + note.animSuffix, true); - } - if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'bf'); - boyfriend.holdTimer = 0; - if (ClientPrefs.doubleGhost) - { - if (!note.isSustainNote && noteRows[note.mustPress?0:1][note.row].length > 1) - { - // potentially have jump anims? - var chord = noteRows[note.mustPress?0:1][note.row]; - var animNote = chord[0]; - var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; - if (boyfriend.mostRecentRow != note.row) - { - boyfriend.playAnim(realAnim, true); - } - - // if (daNote != animNote) - // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); - - boyfriend.mostRecentRow = note.row; - // dad.angle += 15; lmaooooo - doGhostAnim('bf', animToPlay); - } - else{ - boyfriend.playAnim(animToPlay + note.animSuffix, true); - // dad.angle = 0; - } - } - } - if (opponentChart && !note.gfNote && ClientPrefs.charsAndBG) - { - if (!ClientPrefs.doubleGhost) { - dad.playAnim(animToPlay, true); - } - dad.holdTimer = 0; - if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'oppt'); - if (ClientPrefs.doubleGhost) - { - if (!note.isSustainNote && noteRows[note.mustPress?0:1][note.row].length > 1) - { - // potentially have jump anims? - var chord = noteRows[note.mustPress?0:1][note.row]; - var animNote = chord[0]; - var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; - if (dad.mostRecentRow != note.row) - { - dad.playAnim(realAnim, true); - } - - // if (daNote != animNote) - // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); - - // dad.angle += 15; lmaooooo - if (!note.noAnimation && !note.gfNote) - { - if(dad.mostRecentRow != note.row) - doGhostAnim('dad', animToPlay); - dadGhost.color = FlxColor.fromRGB(dad.healthColorArray[0] + 50, dad.healthColorArray[1] + 50, dad.healthColorArray[2] + 50); - dadGhostTween = FlxTween.tween(dadGhost, {alpha: 0}, 0.75, { - ease: FlxEase.linear, - onComplete: function(twn:FlxTween) - { - dadGhostTween = null; - } - }); - } - dad.mostRecentRow = note.row; - } - else{ - dad.playAnim(animToPlay + note.animSuffix, true); - // dad.angle = 0; - } - } - } - - if(note.noteType == 'Hey!') { - if(char.animOffsets.exists('hey')) { - char.playAnim('hey', true); - char.specialAnim = true; - char.heyTimer = 0.6; - } - - if(gf != null && gf.animOffsets.exists('cheer')) { - gf.playAnim('cheer', true); - gf.specialAnim = true; - gf.heyTimer = 0.6; - } - } - } - - if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0) updateRatingCounter(); - if (!ClientPrefs.hideScore && scoreTxtUpdateFrame == 0) updateScore(); - if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); - - if(cpuControlled) { - if (ClientPrefs.botLightStrum) - { - var time:Float = (!ClientPrefs.communityGameBot ? 0.15 : FlxG.random.float(0.05, 0.15)) / playbackRate; - if(note.isSustainNote && (ClientPrefs.showNotes && !note.animation.curAnim.name.endsWith('end'))) { - time += (!ClientPrefs.communityGameBot ? 0.15 : FlxG.random.float(0.05, 0.15)) / playbackRate; - } - var spr:StrumNote = playerStrums.members[note.noteData]; - - if(spr != null) { - if ((ClientPrefs.colorQuants || ClientPrefs.rainbowNotes) && ClientPrefs.showNotes) { - spr.playAnim('confirm', true, note.colorSwap.hue, note.colorSwap.saturation, note.colorSwap.brightness); - } else { - spr.playAnim('confirm', true); - } - spr.resetAnim = time; - } - } - } else if (ClientPrefs.playerLightStrum) { - var spr = playerStrums.members[note.noteData]; - if(spr != null) - { - if ((ClientPrefs.colorQuants || ClientPrefs.rainbowNotes) && ClientPrefs.showNotes) { - spr.playAnim('confirm', true, note.colorSwap.hue, note.colorSwap.saturation, note.colorSwap.brightness); - } else { - spr.playAnim('confirm', true); - } - } - } - note.wasGoodHit = true; - if (ClientPrefs.songLoading) vocals.volume = 1; - - var isSus:Bool = note.isSustainNote; //GET OUT OF MY HEAD, GET OUT OF MY HEAD, GET OUT OF MY HEAD - var leData:Int = Math.round(Math.abs(note.noteData)); - var leType:String = note.noteType; - - callOnLuas('goodNoteHit', [notes.members.indexOf(note), Math.abs(note.noteData), note.noteType, note.isSustainNote]); - callOnLuas((opponentChart ? 'opponentNoteHitFix' : 'goodNoteHitFix'), [notes.members.indexOf(note), leData, leType, isSus]); - - if (!note.isSustainNote) - { - if (shouldKillNotes) - { - note.kill(); - } - notes.remove(note, true); - if (shouldKillNotes) - { - note.destroy(); - } - } - } - } - - public function spawnNoteSplashOnNote(isDad:Bool, note:Note) { - if(ClientPrefs.noteSplashes && note != null) { - var strum:StrumNote = playerStrums.members[note.noteData]; - if (isDad) { - strum = opponentStrums.members[note.noteData]; - } else { - strum = playerStrums.members[note.noteData]; - } - if(strum != null) { - spawnNoteSplash(strum.x, strum.y, note.noteData); - } - } - } - - public function spawnNoteSplash(x:Float, y:Float, data:Int, ?note:Note = null) { - var skin:String = 'noteSplashes'; - if(PlayState.SONG.splashSkin != null && PlayState.SONG.splashSkin.length > 0) skin = PlayState.SONG.splashSkin; - //if (ClientPrefs.splashType == 'VS Impostor') PlayState.SONG.splashSkin = 'impostorNoteSplashes'; - //if (ClientPrefs.splashType == 'Tails Gets Trolled V4') PlayState.SONG.splashSkin = 'tgtNoteSplashes'; - - var hue:Float = 0; - var sat:Float = 0; - var brt:Float = 0; - if (data > -1 && data < ClientPrefs.arrowHSV.length) - { - hue = ClientPrefs.arrowHSV[data][0] / 360; - sat = ClientPrefs.arrowHSV[data][1] / 100; - brt = ClientPrefs.arrowHSV[data][2] / 100; - if(note != null) { - skin = note.noteSplashTexture; - hue = note.noteSplashHue; - sat = note.noteSplashSat; - brt = note.noteSplashBrt; - } - } - - var splash:NoteSplash = grpNoteSplashes.recycle(NoteSplash); - splash.setupNoteSplash(x, y, data, skin, hue, sat, brt); - grpNoteSplashes.add(splash); - } - - var fastCarCanDrive:Bool = true; - - function resetFastCar():Void - { - fastCar.x = -12600; - fastCar.y = FlxG.random.int(140, 250); - fastCar.velocity.x = 0; - fastCarCanDrive = true; - } - - var carTimer:FlxTimer; - function fastCarDrive() - { - //trace('Car drive'); - FlxG.sound.play(Paths.soundRandom('carPass', 0, 1), 0.7); - - fastCar.velocity.x = (FlxG.random.int(170, 220) / FlxG.elapsed) * 3; - fastCarCanDrive = false; - carTimer = new FlxTimer().start(2, function(tmr:FlxTimer) - { - resetFastCar(); - carTimer = null; - }); - } - - var trainMoving:Bool = false; - var trainFrameTiming:Float = 0; - - var trainCars:Int = 8; - var trainFinishing:Bool = false; - var trainCooldown:Int = 0; - - function trainStart():Void - { - trainMoving = true; - if (!trainSound.playing) - trainSound.play(true); - } - - var startedMoving:Bool = false; - - function updateTrainPos():Void - { - if (trainSound.time >= 4700) - { - startedMoving = true; - if (gf != null) - { - gf.playAnim('hairBlow'); - gf.specialAnim = true; - } - } - - 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(gf != null) - { - gf.danced = false; //Sets head to the correct position once the animation ends - gf.playAnim('hairFall'); - gf.specialAnim = true; - } - 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)); - if(!ClientPrefs.lowQuality) halloweenBG.animation.play('halloweem bg lightning strike'); - - lightningStrikeBeat = curBeat; - lightningOffset = FlxG.random.int(8, 24); - - if(boyfriend.animOffsets.exists('scared')) { - boyfriend.playAnim('scared', true); - } - - if(gf != null && gf.animOffsets.exists('scared')) { - gf.playAnim('scared', true); - } - - if(ClientPrefs.camZooms) { - FlxG.camera.zoom += 0.015; - camHUD.zoom += 0.03; - - if(!camZooming) { //Just a way for preventing it to be permanently zoomed until Skid & Pump hits a note - FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom}, 0.5); - FlxTween.tween(camHUD, {zoom: 1}, 0.5); - } - } - - if(ClientPrefs.flashing) { - halloweenWhite.alpha = 0.4; - FlxTween.tween(halloweenWhite, {alpha: 0.5}, 0.075); - FlxTween.tween(halloweenWhite, {alpha: 0}, 0.25, {startDelay: 0.15}); - } - } - - function killHenchmen():Void - { - if(!ClientPrefs.lowQuality && ClientPrefs.violence && curStage == 'limo') { - if(limoKillingState < 1) { - limoMetalPole.x = -400; - limoMetalPole.visible = true; - limoLight.visible = true; - limoCorpse.visible = false; - limoCorpseTwo.visible = false; - limoKillingState = 1; - - #if ACHIEVEMENTS_ALLOWED - Achievements.henchmenDeath++; - FlxG.save.data.henchmenDeath = Achievements.henchmenDeath; - var achieve:String = checkForAchievement(['roadkill_enthusiast']); - if (achieve != null) { - startAchievement(achieve); - } else { - FlxG.save.flush(); - } - FlxG.log.add('Deaths: ' + Achievements.henchmenDeath); - #end - } - } - } - - function resetLimoKill():Void - { - if(curStage == 'limo') { - limoMetalPole.x = -500; - limoMetalPole.visible = false; - limoLight.x = -500; - limoLight.visible = false; - limoCorpse.x = -500; - limoCorpse.visible = false; - limoCorpseTwo.x = -500; - limoCorpseTwo.visible = false; - } - } - - var tankX:Float = 400; - var tankSpeed:Float = FlxG.random.float(5, 7); - var tankAngle:Float = FlxG.random.int(-90, 45); - - function moveTank(?elapsed:Float = 0):Void - { - if(!inCutscene) - { - tankAngle += elapsed * tankSpeed; - tankGround.angle = tankAngle - 90 + 15; - tankGround.x = tankX + 1500 * Math.cos(Math.PI / 180 * (1 * tankAngle + 180)); - tankGround.y = 1300 + 1100 * Math.sin(Math.PI / 180 * (1 * tankAngle + 180)); - } - } - - override function destroy() { - for (lua in luaArray) { - lua.call('onDestroy', []); - lua.stop(); - } - luaArray = []; - - #if hscript - if(FunkinLua.hscript != null) FunkinLua.hscript = null; - #end - - if(!ClientPrefs.controllerMode) - { - FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyPress); - FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, onKeyRelease); - } - FlxAnimationController.globalSpeed = 1; - FlxG.sound.music.pitch = 1; - cpp.vm.Gc.enable(true); - KillNotes(); - super.destroy(); - } - - public static function cancelMusicFadeTween() { - if(FlxG.sound.music.fadeTween != null) { - FlxG.sound.music.fadeTween.cancel(); - } - FlxG.sound.music.fadeTween = null; - } - - var lastStepHit:Int = -1; - override function stepHit() - { - super.stepHit(); - - if (tankmanAscend) - { - if (curStep >= 896 && curStep <= 1152) moveCameraSection(); - switch (curStep) - { - case 896: - { - opponentStrums.forEachAlive(function(daNote:FlxSprite) - { - FlxTween.tween(daNote, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - }); - FlxTween.tween(EngineWatermark, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(timeBar, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(judgementCounter, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(scoreTxt, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(healthBar, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(healthBarBG, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(iconP1, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(iconP2, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(timeTxt, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - dad.velocity.y = -35; - } - case 906: - { - playerStrums.forEachAlive(function(daNote:FlxSprite) - { - FlxTween.tween(daNote, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); - }); - } - case 1020: - { - playerStrums.forEachAlive(function(daNote:FlxSprite) - { - FlxTween.tween(daNote, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - }); - } - case 1024: - dad.velocity.y = 0; - boyfriend.velocity.y = -33.5; - case 1151: - cameraSpeed = 100; - case 1152: - { - FlxG.camera.flash(FlxColor.WHITE, 1); - opponentStrums.forEachAlive(function(daNote:FlxSprite) - { - FlxTween.tween(daNote, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - }); - FlxTween.tween(EngineWatermark, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(timeBar, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(judgementCounter, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(healthBar, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(healthBarBG, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(scoreTxt, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(iconP1, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(iconP2, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - FlxTween.tween(timeTxt, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); - dad.x = 100; - dad.y = 280; - boyfriend.x = 810; - boyfriend.y = 450; - dad.velocity.y = 0; - boyfriend.velocity.y = 0; - } - case 1153: - cameraSpeed = 1; - } - } - var gamerValue = 20 * playbackRate; - if (!ClientPrefs.noSyncing && ClientPrefs.songLoading && playbackRate < 256) //much better resync code, doesn't just resync every step!! - { - if (FlxG.sound.music.time > Conductor.songPosition + gamerValue - || FlxG.sound.music.time < Conductor.songPosition - gamerValue - || FlxG.sound.music.time < 500 && ClientPrefs.startingSync) - { - resyncVocals(); - } - } - - if(curStep == lastStepHit) { - return; - } - - lastStepHit = curStep; - setOnLuas('curStep', curStep); - callOnLuas('onStepHit', []); - } - - var lightningStrikeBeat:Int = 0; - var lightningOffset:Int = 8; - - var lastBeatHit:Int = -1; - - override function beatHit() - { - super.beatHit(); - - if(ClientPrefs.timeBounce) - { - if(timeTxtTween != null) { - timeTxtTween.cancel(); - } - timeTxt.scale.x = 1.075; - timeTxt.scale.y = 1.075; - timeTxtTween = FlxTween.tween(timeTxt.scale, {x: 1, y: 1}, 0.2, { - onComplete: function(twn:FlxTween) { - timeTxtTween = null; - } - }); - } - - if (curBeat % 32 == 0 && randomSpeedThing) - { - var randomShit = FlxMath.roundDecimal(FlxG.random.float(0.4, 3), 2); - lerpSongSpeed(randomShit, 1); - } - if (camZooming && !endingSong && !startingSong && FlxG.camera.zoom < 1.35 && ClientPrefs.camZooms && curBeat % camBopInterval == 0 && !softlocked) - { - FlxG.camera.zoom += 0.015 * camBopIntensity; - camHUD.zoom += 0.03 * camBopIntensity; - } /// WOOO YOU CAN NOW MAKE IT AWESOME - - if (generatedMusic) - { - if (ClientPrefs.showNotes) notes.sort(FlxSort.byY, ClientPrefs.downScroll ? FlxSort.ASCENDING : FlxSort.DESCENDING); - } - - if (ClientPrefs.iconBounceType == 'Dave and Bambi') { - var funny:Float = Math.max(Math.min(healthBar.value,(maxHealth/0.95)),0.1); - - //health icon bounce but epic - if (!opponentChart) - { - iconP1.setGraphicSize(Std.int(iconP1.width + (50 * (funny + 0.1))),Std.int(iconP1.height - (25 * funny))); - iconP2.setGraphicSize(Std.int(iconP2.width + (50 * ((2 - funny) + 0.1))),Std.int(iconP2.height - (25 * ((2 - funny) + 0.1)))); - } else { - iconP2.setGraphicSize(Std.int(iconP2.width + (50 * funny)),Std.int(iconP2.height - (25 * funny))); - iconP1.setGraphicSize(Std.int(iconP1.width + (50 * ((2 - funny) + 0.1))),Std.int(iconP1.height - (25 * ((2 - funny) + 0.1)))); - } - } - if (ClientPrefs.iconBounceType == 'Old Psych') { - iconP1.setGraphicSize(Std.int(iconP1.width + 30)); - iconP2.setGraphicSize(Std.int(iconP2.width + 30)); - } - if (ClientPrefs.iconBounceType == 'Strident Crisis') { - var funny:Float = (healthBar.percent * 0.01) + 0.01; - - //health icon bounce but epic - iconP1.setGraphicSize(Std.int(iconP1.width + (50 * (2 + funny))),Std.int(iconP2.height - (25 * (2 + funny)))); - iconP2.setGraphicSize(Std.int(iconP2.width + (50 * (2 - funny))),Std.int(iconP2.height - (25 * (2 - funny)))); - - iconP1.scale.set(1.1, 0.8); - iconP2.scale.set(1.1, 0.8); - - FlxTween.angle(iconP1, -15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); - FlxTween.angle(iconP2, 15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); - - FlxTween.tween(iconP1, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 * gfSpeed, {ease: FlxEase.quadOut}); - FlxTween.tween(iconP2, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 * gfSpeed, {ease: FlxEase.quadOut}); - - iconP1.updateHitbox(); - iconP2.updateHitbox(); - } - if (ClientPrefs.iconBounceType == 'Plank Engine') { - iconP1.scale.x = 1.3; - iconP1.scale.y = 0.75; - iconP2.scale.x = 1.3; - iconP2.scale.y = 0.75; - FlxTween.cancelTweensOf(iconP1); - FlxTween.cancelTweensOf(iconP2); - FlxTween.tween(iconP1, {"scale.x": 1, "scale.y": 1}, Conductor.crochet / 1000, {ease: FlxEase.backOut}); - FlxTween.tween(iconP2, {"scale.x": 1, "scale.y": 1}, Conductor.crochet / 1000, {ease: FlxEase.backOut}); - if (curBeat % 4 == 0) { - iconP1.offset.x = 10; - iconP2.offset.x = -10; - iconP1.angle = -15; - iconP2.angle = 15; - FlxTween.tween(iconP1, {"offset.x": 0, angle: 0}, Conductor.crochet / 1000, {ease: FlxEase.expoOut}); - FlxTween.tween(iconP2, {"offset.x": 0, angle: 0}, Conductor.crochet / 1000, {ease: FlxEase.expoOut}); - } - } - if (ClientPrefs.iconBounceType == 'New Psych') { - iconP1.scale.set(1.2, 1.2); - iconP2.scale.set(1.2, 1.2); - } - - iconP1.updateHitbox(); - iconP2.updateHitbox(); - - if (gf != null && curBeat % Math.round(gfSpeed * gf.danceEveryNumBeats) == 0 && gf.animation.curAnim != null && !gf.animation.curAnim.name.startsWith("sing") && !gf.stunned) - { - gf.dance(); - } - if (curBeat % gfSpeed == 0 && ClientPrefs.iconBounceType == 'Golden Apple') { - curBeat % (gfSpeed * 2) == 0 * playbackRate ? { - iconP1.scale.set(1.1, 0.8); - iconP2.scale.set(1.1, 1.3); - - FlxTween.angle(iconP1, -15, 0, Conductor.crochet / 1300 / playbackRate, {ease: FlxEase.quadOut}); - FlxTween.angle(iconP2, 15, 0, Conductor.crochet / 1300 / playbackRate, {ease: FlxEase.quadOut}); - } : { - iconP1.scale.set(1.1, 1.3); - iconP2.scale.set(1.1, 0.8); - - FlxTween.angle(iconP2, -15, 0, Conductor.crochet / 1300 / playbackRate, {ease: FlxEase.quadOut}); - FlxTween.angle(iconP1, 15, 0, Conductor.crochet / 1300 / playbackRate, {ease: FlxEase.quadOut}); - } - - FlxTween.tween(iconP1, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 / playbackRate * gfSpeed, {ease: FlxEase.quadOut}); - FlxTween.tween(iconP2, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 / playbackRate * gfSpeed, {ease: FlxEase.quadOut}); - - iconP1.updateHitbox(); - iconP2.updateHitbox(); - } - if (ClientPrefs.iconBounceType == 'VS Steve') { - if (curBeat % gfSpeed == 0) - { - curBeat % (gfSpeed * 2) == 0 ? - { - iconP1.scale.set(1.1, 0.8); - iconP2.scale.set(1.1, 1.3); - //FlxTween.angle(iconP2, -15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); - //FlxTween.angle(iconP1, 15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); - } - : - { - iconP1.scale.set(1.1, 1.3); - iconP2.scale.set(1.1, 0.8); - FlxTween.angle(iconP1, -15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); - FlxTween.angle(iconP2, 15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); - - } - - FlxTween.tween(iconP1, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 * gfSpeed, {ease: FlxEase.quadOut}); - FlxTween.tween(iconP2, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 * gfSpeed, {ease: FlxEase.quadOut}); - - iconP1.updateHitbox(); - iconP2.updateHitbox(); - } - } - - if (ClientPrefs.charsAndBG) { - if (curBeat % boyfriend.danceEveryNumBeats == 0 && boyfriend.animation.curAnim != null && !boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.stunned) - { - boyfriend.dance(); - } - if (curBeat % dad.danceEveryNumBeats == 0 && dad.animation.curAnim != null && !dad.animation.curAnim.name.startsWith('sing') && !dad.stunned) - { - dad.dance(); - } - - switch (curStage) - { - case 'tank': - if(!ClientPrefs.lowQuality) tankWatchtower.dance(); - foregroundSprites.forEach(function(spr:BGSprite) - { - spr.dance(); - }); - - case 'school': - if(!ClientPrefs.lowQuality) { - bgGirls.dance(); - } - - case 'mall': - if(!ClientPrefs.lowQuality) { - upperBoppers.dance(true); - } - - if(heyTimer <= 0) bottomBoppers.dance(true); - santa.dance(true); - - case 'limo': - if(!ClientPrefs.lowQuality) { - grpLimoDancers.forEach(function(dancer:BackgroundDancer) - { - dancer.dance(); - }); - } - - if (FlxG.random.bool(10) && fastCarCanDrive) - fastCarDrive(); - case "philly": - if (!trainMoving) - trainCooldown += 1; - - if (curBeat % 4 == 0) - { - curLight = FlxG.random.int(0, phillyLightsColors.length - 1, [curLight]); - phillyWindow.color = phillyLightsColors[curLight]; - phillyWindow.alpha = 1; - } - - if (curBeat % 8 == 4 && FlxG.random.bool(30) && !trainMoving && trainCooldown > 8) - { - trainCooldown = FlxG.random.int(-4, 0); - trainStart(); - } - } - - if (curStage == 'spooky' && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset) - { - lightningStrikeShit(); - } - } - lastBeatHit = curBeat; - - setOnLuas('curBeat', curBeat); //DAWGG????? - callOnLuas('onBeatHit', []); - } - - override function sectionHit() - { - super.sectionHit(); - - if (SONG.notes[curSection] != null) - { - if (generatedMusic && !endingSong && !isCameraOnForcedPos) - { - moveCameraSection(); - } - - /*if (camZooming && FlxG.camera.zoom < 1.35 && ClientPrefs.camZooms && camBopInterval == 0 && camBopIntensity == 0) - { - FlxG.camera.zoom += 0.015 * camZoomingMult; - camHUD.zoom += 0.03 * camZoomingMult; - }*/ - - if (SONG.notes[curSection].changeBPM) - { - Conductor.changeBPM(SONG.notes[curSection].bpm); - setOnLuas('curBpm', Conductor.bpm); - setOnLuas('crochet', Conductor.crochet); - setOnLuas('stepCrochet', Conductor.stepCrochet); - } - setOnLuas('mustHitSection', SONG.notes[curSection].mustHitSection); - setOnLuas('altAnim', SONG.notes[curSection].altAnim); - setOnLuas('gfSection', SONG.notes[curSection].gfSection); - } - - setOnLuas('curSection', curSection); - callOnLuas('onSectionHit', []); - } - - #if LUA_ALLOWED - public function startLuasOnFolder(luaFile:String) - { - for (script in luaArray) - { - if(script.scriptName == luaFile) return false; - } - - #if MODS_ALLOWED - var luaToLoad:String = Paths.modFolders(luaFile); - if(FileSystem.exists(luaToLoad)) - { - luaArray.push(new FunkinLua(luaToLoad)); - return true; - } - else - { - luaToLoad = Paths.getPreloadPath(luaFile); - if(FileSystem.exists(luaToLoad)) - { - luaArray.push(new FunkinLua(luaToLoad)); - return true; - } - } - #elseif sys - var luaToLoad:String = Paths.getPreloadPath(luaFile); - if(OpenFlAssets.exists(luaToLoad)) - { - luaArray.push(new FunkinLua(luaToLoad)); - return true; - } - #end - return false; - } - #end - - public function callOnLuas(event:String, args:Array, ignoreStops = true, exclusions:Array = null, excludeValues:Array = null):Dynamic { - var returnVal = FunkinLua.Function_Continue; - #if LUA_ALLOWED - if(exclusions == null) exclusions = []; - if(excludeValues == null) excludeValues = []; - - for (script in luaArray) { - if(exclusions.contains(script.scriptName)) - continue; - - var myValue = script.call(event, args); - if(myValue == FunkinLua.Function_StopLua && !ignoreStops) - break; - - if(myValue != null && myValue != FunkinLua.Function_Continue) { - returnVal = myValue; - } - } - #end - return returnVal; - } - - public function setOnLuas(variable:String, arg:Dynamic) { - #if LUA_ALLOWED - for (i in 0...luaArray.length) { - luaArray[i].set(variable, arg); - } - #end - } - - function StrumPlayAnim(isDad:Bool, id:Int, time:Float) { - var spr:StrumNote = isDad ? opponentStrums.members[id] : playerStrums.members[id]; - - if(spr != null) { - spr.playAnim('confirm', true); - spr.resetAnim = time; - } - } - - public function updateRatingCounter() { - judgeCountUpdateFrame++; - if (!ClientPrefs.noMarvJudge) - { - judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nMarvelous!!!: ' + marvs + '\nSicks!!: ' + sicks + '\nGoods!: ' + goods + '\nBads: ' + bads + '\nShits: ' + shits + '\nMisses: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - - if (ClientPrefs.hudType == 'Doki Doki+') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nVery Doki: ' + marvs + '\nDoki: ' + sicks + '\nGood: ' + goods + '\nOK: ' + bads + '\nNO: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - - if (ClientPrefs.hudType == 'VS Impostor') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSO SUSSY: ' + marvs + '\nSussy: ' + sicks + '\nSus: ' + goods + '\nSad: ' + bads + '\nAss: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - } - if (ClientPrefs.noMarvJudge) - { - judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSicks!!: ' + sicks + '\nGoods!: ' + goods + '\nBads: ' + bads + '\nShits: ' + shits + '\nMisses: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - - if (ClientPrefs.hudType == 'Doki Doki+') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nDoki: ' + sicks + '\nGood: ' + goods + '\nOK: ' + bads + '\nNO: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - - if (ClientPrefs.hudType == 'VS Impostor') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSussy: ' + sicks + '\nSus: ' + goods + '\nSad: ' + bads + '\nAss: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); - } - judgementCounter.text += (ClientPrefs.showNPS ? '\nNPS (Max): ' + FlxStringUtil.formatMoney(nps, false) + ' (' + FlxStringUtil.formatMoney(maxNPS, false) + ')' : ''); - if (ClientPrefs.opponentRateCount) judgementCounter.text += '\n\nOpponent Hits: ' + FlxStringUtil.formatMoney(enemyHits, false) + ' / ' + FlxStringUtil.formatMoney(opponentNoteTotal, false) + ' (' + FlxMath.roundDecimal((enemyHits / opponentNoteTotal) * 100, 2) + '%)' + (ClientPrefs.showNPS ? '\nOpponent NPS (Max): ' + FlxStringUtil.formatMoney(oppNPS, false) + ' (' + FlxStringUtil.formatMoney(maxOppNPS, false) + ')' : ''); - } - - public var ratingName:String = '?'; - public var ratingString:String; - public var ratingPercent:Float; - public var ratingFC:String; - public var ratingCool:String; - public function RecalculateRating(badHit:Bool = false) { - setOnLuas('score', songScore); - setOnLuas('misses', songMisses); - setOnLuas('hits', songHits); - - var ret:Dynamic = callOnLuas('onRecalculateRating', [], false); - if(ret != FunkinLua.Function_Stop) - { - if(totalPlayed < 1) //Prevent divide by 0 - ratingName = '?'; - else - { - // Rating Percent - ratingPercent = Math.min(1, Math.max(0, totalNotesHit / totalPlayed)); - //trace((totalNotesHit / totalPlayed) + ', Total: ' + totalPlayed + ', notes hit: ' + totalNotesHit); - - if (Math.isNaN(ratingPercent)) - ratingString = '?'; - - // Rating Name - if(ratingPercent >= 1) - { - ratingName = ratingStuff[ratingStuff.length-1][0]; //Uses last string - } - else - { - for (i in 0...ratingStuff.length-1) - { - if(ratingPercent < ratingStuff[i][1]) - { - ratingName = ratingStuff[i][0]; - break; - } - } - } - } - - // Rating FC - ratingFC = ""; - if (totalPlayed == 0) ratingFC = "No Play"; - if (marvs > 0) ratingFC = "MFC"; - if (sicks > 0) ratingFC = "SFC"; - if (goods > 0) ratingFC = "GFC"; - if (bads > 0) ratingFC = "BFC"; - if (shits > 0) ratingFC = "FC"; - if (songMisses > 0 && songMisses < 10) ratingFC = "SDCB"; - if (songMisses >= 10) ratingFC = "Clear"; - if (songMisses >= 100) ratingFC = "TDSB"; - if (songMisses >= 1000) ratingFC = "QDSB"; - if (songMisses >= 100000) ratingFC = "STDCB"; - else if (songMisses >= 10000000) ratingFC = "SPDCB"; //i have no idea how you'd get a million misses but oh well - - - if (!ClientPrefs.longFCName) - { - if (ClientPrefs.hudType == "VS Impostor") - { - if (totalPlayed == 0) ratingFC = " [No Play]"; - if (marvs > 0) ratingFC = " [MFC]"; - if (sicks > 0) ratingFC = " [SFC]"; - if (goods > 0) ratingFC = " [GFC]"; - if (bads > 0) ratingFC = " [BFC]"; - if (shits > 0) ratingFC = " [FC]"; - if (songMisses > 0 && songMisses < 10) ratingFC = " [SDCB]"; - if (songMisses >= 10) ratingFC = " [Clear]"; - if (songMisses >= 100) ratingFC = " [TDSB]"; - if (songMisses >= 1000) ratingFC = " [QDSB]"; - if (songMisses >= 100000) ratingFC = " [STDCB]"; - else if (songMisses >= 10000000) ratingFC = " [SPDCB]"; //i have no idea how you'd get a million misses but oh well - } - - if (ClientPrefs.hudType == "Tails Gets Trolled V4") - { - if (totalPlayed == 0) ratingFC = "No Play"; - if (marvs > 0) ratingFC = "KFC"; - if (sicks > 0) ratingFC = "AFC"; - if (goods > 0) ratingFC = "CFC"; - if (bads > 0) ratingFC = "SDC"; - if (shits > 0) ratingFC = "FC"; - if (songMisses > 0 && songMisses < 10) ratingFC = "SDCB"; - if (songMisses >= 10) ratingFC = "Clear"; - if (songMisses >= 100) ratingFC = "TDSB"; - if (songMisses >= 1000) ratingFC = "QDSB"; - if (songMisses >= 100000) ratingFC = "STDCB"; - else if (songMisses >= 10000000) ratingFC = "SPDCB"; //i have no idea how you'd get a million misses but oh well - } - - // Rating FC - if (ClientPrefs.hudType == 'Kade Engine' || ClientPrefs.hudType == 'Doki Doki+') { - ratingFC = "?"; - if (totalPlayed == 0) ratingFC = "No Play"; - if (marvs > 0) ratingFC = "(MFC)"; - if (sicks > 0) ratingFC = "(SFC)"; - if (goods > 0) ratingFC = "(GFC)"; - if (bads > 0) ratingFC = "(BFC)"; - if (shits > 0) ratingFC = "(FC)"; - if (songMisses > 0 && songMisses < 10) ratingFC = "(SDCB)"; - if (songMisses >= 10) ratingFC = "(Clear)"; - if (songMisses >= 100) ratingFC = "(TDSB)"; - if (songMisses >= 1000) ratingFC = "(QDSB)"; - if (songMisses >= 100000) ratingFC = "(STDCB)"; - else if (songMisses >= 10000000) ratingFC = "(SPDCB)"; //i have no idea how you'd get a million misses but oh well - } - } - if (ClientPrefs.longFCName) - { - if (totalPlayed == 0) ratingFC = "No Play"; - if (marvs > 0) ratingFC = "Marvelous Full Combo"; - if (sicks > 0) ratingFC = "Sick Full Combo"; - if (goods > 0) ratingFC = "Great Full Combo"; - if (bads > 0) ratingFC = "Bad Full Combo"; - if (shits > 0) ratingFC = "Shit Full Combo"; - if (songMisses > 0 && songMisses < 10) ratingFC = "Single Digit Combo Breaks"; - if (songMisses >= 10) ratingFC = "Double Digit Combo Breaks"; - if (songMisses >= 100) ratingFC = "Triple Digit Combo Breaks"; - if (songMisses >= 1000) ratingFC = "Quadruple Digit Combo Breaks"; - if (songMisses >= 10000) ratingFC = "Quintuple Digit Combo Breaks"; - if (songMisses >= 100000) ratingFC = "Sixtuple Digit Combo Breaks"; - else if (songMisses >= 10000000) ratingFC = "Septuple Digit Combo Breaks"; //i have no idea how you'd get a million misses but oh well - if (ClientPrefs.hudType == "VS Impostor") - { - if (totalPlayed == 0) ratingFC = " [No Play]"; - if (marvs > 0) ratingFC = " [Marvelous Full Combo]"; - if (sicks > 0) ratingFC = " [Sick Full Combo]"; - if (goods > 0) ratingFC = " [Great Full Combo]"; - if (bads > 0) ratingFC = " [Bad Full Combo]"; - if (shits > 0) ratingFC = " [Shit Full Combo]"; - if (songMisses > 0 && songMisses < 10) ratingFC = " [Single Digit Combo Breaks]"; - if (songMisses >= 10) ratingFC = " [Double Digit Combo Breaks]"; - if (songMisses >= 100) ratingFC = " [Triple Digit Combo Breaks]"; - if (songMisses >= 1000) ratingFC = " [Quadruple Digit Combo Breaks]"; - if (songMisses >= 10000) ratingFC = " [Quintuple Digit Combo Breaks]"; - if (songMisses >= 100000) ratingFC = " [Sixtuple Digit Combo Breaks]"; - else if (songMisses >= 10000000) ratingFC = " [Septuple Digit Combo Breaks]"; //i have no idea how you'd get a million misses but oh well - } - - if (ClientPrefs.hudType == "Tails Gets Trolled V4") - { - if (totalPlayed == 0) ratingFC = "No Play"; - if (marvs > 0) ratingFC = "Killer Full Combo"; - if (sicks > 0) ratingFC = "Awesome Full Combo"; - if (goods > 0) ratingFC = "Cool Full Combo"; - if (bads > 0) ratingFC = "Gay Full Combo"; - if (shits > 0) ratingFC = "Retarded Full Combo"; - if (songMisses > 0 && songMisses < 10) ratingFC = "Single Digit Combo Breaks"; - if (songMisses >= 10) ratingFC = "Double Digit Combo Breaks"; - if (songMisses >= 100) ratingFC = "Triple Digit Combo Breaks"; - if (songMisses >= 1000) ratingFC = "Quadruple Digit Combo Breaks"; - if (songMisses >= 10000) ratingFC = "Quintuple Digit Combo Breaks"; - if (songMisses >= 100000) ratingFC = "Sixtuple Digit Combo Breaks"; - else if (songMisses >= 10000000) ratingFC = "Septuple Digit Combo Breaks"; //i have no idea how you'd get a million misses but oh well - } - - // Rating FC - if (ClientPrefs.hudType == 'Kade Engine' || ClientPrefs.hudType == 'Doki Doki+') { - ratingFC = "?"; - if (totalPlayed == 0) ratingFC = "(No Play)"; - if (marvs > 0) ratingFC = "(Marvelous Full Combo)"; - if (sicks > 0) ratingFC = "(Sick Full Combo)"; - if (goods > 0) ratingFC = "(Great Full Combo)"; - if (bads > 0) ratingFC = "(Bad Full Combo)"; - if (shits > 0) ratingFC = "(Shit Full Combo)"; - if (songMisses > 0 && songMisses < 10) ratingFC = "(Single Digit Combo Breaks)"; - if (songMisses >= 10) ratingFC = "(Double Digit Combo Breaks)"; - if (songMisses >= 100) ratingFC = "(Triple Digit Combo Breaks)"; - if (songMisses >= 1000) ratingFC = "(Quadruple Digit Combo Breaks)"; - if (songMisses >= 10000) ratingFC = "(Quintuple Digit Combo Breaks)"; - if (songMisses >= 100000) ratingFC = "(Sixtuple Digit Combo Breaks)"; - else if (songMisses >= 10000000) ratingFC = "(Septuple Digit Combo Breaks)"; //i have no idea how you'd get a million misses but oh well - } - } - - ratingCool = ""; - if (ratingPercent*100 <= 60) ratingCool = " F"; - if (ratingPercent*100 >= 60) ratingCool = " D"; - if (ratingPercent*100 >= 60) ratingCool = " C"; - if (ratingPercent*100 >= 70) ratingCool = " B"; - if (ratingPercent*100 >= 80) ratingCool = " A"; - if (ratingPercent*100 >= 85) ratingCool = " A."; - if (ratingPercent*100 >= 90) ratingCool = " A:"; - if (ratingPercent*100 >= 93) ratingCool = " AA"; - if (ratingPercent*100 >= 96.50) ratingCool = " AA."; - if (ratingPercent*100 >= 99) ratingCool = " AA:"; - if (ratingPercent*100 >= 99.70) ratingCool = " AAA"; - if (ratingPercent*100 >= 99.80) ratingCool = " AAA."; - if (ratingPercent*100 >= 99.90) ratingCool = " AAA:"; - if (ratingPercent*100 >= 99.955) ratingCool = " AAAA"; - if (ratingPercent*100 >= 99.970) ratingCool = " AAAA."; - if (ratingPercent*100 >= 99.980) ratingCool = " AAAA:"; - if (ratingPercent*100 >= 99.9935) ratingCool = " AAAAA"; - } - - setOnLuas('rating', ratingPercent); - setOnLuas('ratingName', ratingName); - setOnLuas('ratingFC', ratingFC); - setOnLuas('ratingCool', ratingCool); - } - - #if ACHIEVEMENTS_ALLOWED - private function checkForAchievement(achievesToCheck:Array = null):String - { - if(chartingMode) return null; - - var usedPractice:Bool = (ClientPrefs.getGameplaySetting('practice', false) || ClientPrefs.getGameplaySetting('botplay', false)); - for (i in 0...achievesToCheck.length) { - var achievementName:String = achievesToCheck[i]; - if(!Achievements.isAchievementUnlocked(achievementName) && !cpuControlled && Achievements.exists(achievementName)) { - var unlock:Bool = false; - - if (achievementName.contains(WeekData.getWeekFileName()) && achievementName.endsWith('nomiss')) // any FC achievements, name should be "weekFileName_nomiss", e.g: "weekd_nomiss"; - { - if(isStoryMode && campaignMisses + songMisses < 1 && CoolUtil.difficultyString() == 'HARD' - && storyPlaylist.length <= 1 && !changedDifficulty && !usedPractice) - unlock = true; - } - switch(achievementName) - { - case 'ur_bad': - if(ratingPercent < 0.2 && !practiceMode) { - unlock = true; - } - case 'ur_good': - if(ratingPercent >= 1 && !usedPractice) { - unlock = true; - } - case 'roadkill_enthusiast': - if(Achievements.henchmenDeath >= 100) { - unlock = true; - } - case 'oversinging': - if(boyfriend.holdTimer >= 10 && !usedPractice) { - unlock = true; - } - case 'hype': - if(!boyfriendIdled && !usedPractice) { - unlock = true; - } - case 'two_keys': - if(!usedPractice) { - var howManyPresses:Int = 0; - for (j in 0...keysPressed.length) { - if(keysPressed[j]) howManyPresses++; - } - - if(howManyPresses <= 2) { - unlock = true; - } - } - case 'toastie': - if(/*ClientPrefs.framerate <= 60 &&*/ !ClientPrefs.shaders && ClientPrefs.lowQuality && !ClientPrefs.globalAntialiasing) { - unlock = true; - } - case 'debugger': - if(Paths.formatToSongPath(SONG.song) == 'test' && !usedPractice) { - unlock = true; - } - } - - if(unlock) { - Achievements.unlockAchievement(achievementName); - return achievementName; - } - } - } - return null; - } - #end - - var curLight:Int = -1; - var curLightEvent:Int = -1; -} -//WEVE DONE IT, WE'VE HIT 10,000 LINES +package; + +import flixel.graphics.FlxGraphic; +#if desktop +import Discord.DiscordClient; +#end +import Section.SwagSection; +import Song.SwagSong; +import WiggleEffect.WiggleEffectType; +import flixel.FlxBasic; +import flixel.FlxCamera; +import flixel.FlxG; +import flixel.FlxGame; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.FlxState; +import flixel.FlxSubState; +import flixel.addons.display.FlxGridOverlay; +import flixel.addons.effects.FlxTrail; +import flixel.addons.effects.FlxTrailArea; +import flixel.addons.effects.chainable.FlxEffectSprite; +import flixel.addons.effects.chainable.FlxWaveEffect; +import flixel.addons.transition.FlxTransitionableState; +import flixel.graphics.atlas.FlxAtlas; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.system.FlxSound; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.ui.FlxBar; +import flixel.util.FlxCollision; +import flixel.util.FlxColor; +import flixel.util.FlxSort; +import flixel.util.FlxStringUtil; +import flixel.util.FlxTimer; +import haxe.Json; +import haxe.Int64; +import lime.utils.Assets; +import openfl.Lib; +import openfl.filters.BitmapFilter; +import openfl.display.BlendMode; +import openfl.display.StageQuality; +import openfl.filters.BitmapFilter; +import openfl.utils.Assets as OpenFlAssets; +import editors.ChartingState; +import editors.CharacterEditorState; +import flixel.group.FlxSpriteGroup; +import flixel.input.keyboard.FlxKey; +import Note.EventNote; +import openfl.events.KeyboardEvent; +import flixel.effects.particles.FlxEmitter; +import flixel.effects.particles.FlxParticle; +import flixel.util.FlxSave; +import flixel.animation.FlxAnimationController; +import animateatlas.AtlasFrameMaker; +import Achievements; +import StageData; +import FunkinLua; +import DialogueBoxPsych; +import Conductor.Rating; +import Shaders; +import flixel.util.FlxPool; + + +#if !flash +import flixel.addons.display.FlxRuntimeShader; +import openfl.filters.ShaderFilter; +#end + +#if sys +import sys.FileSystem; +import sys.io.File; +#end + +#if VIDEOS_ALLOWED +#if (hxCodec >= "3.0.0") +import hxcodec.flixel.FlxVideo as MP4Handler; +#elseif (hxCodec == "2.6.1") +import hxcodec.VideoHandler as MP4Handler; +#elseif (hxCodec == "2.6.0") +import VideoHandler as MP4Handler; +#else +import vlc.MP4Handler; +#end +#end + +import ColorSwap.ColorSwapShader; //for motion blur + + +using StringTools; + +class PlayState extends MusicBeatState +{ + var noteRows:Array>> = [[],[]]; + private var singAnimations:Array = ['singLEFT', 'singDOWN', 'singUP', 'singRIGHT']; + + public static var instance:PlayState; + public static var STRUM_X = 48.5; + public static var STRUM_X_MIDDLESCROLL = -278; + + public static var ratingStuff:Array = []; + + + private var tauntKey:Array; + + public var shader_chromatic_abberation:ChromaticAberrationEffect; + public var camGameShaders:Array = []; + public var camHUDShaders:Array = []; + public var camOtherShaders:Array = []; + + //event variables + private var isCameraOnForcedPos:Bool = false; + + #if (haxe >= "4.0.0") + public var boyfriendMap:Map = new Map(); + public var dadMap:Map = new Map(); + public var gfMap:Map = new Map(); + public var variables:Map = new Map(); + public var modchartTweens:Map = new Map(); + public var modchartSprites:Map = new Map(); + public var modchartTimers:Map = new Map(); + public var modchartSounds:Map = new Map(); + public var modchartTexts:Map = new Map(); + public var modchartSaves:Map = new Map(); + #else + public var boyfriendMap:Map = new Map(); + public var dadMap:Map = new Map(); + public var gfMap:Map = new Map(); + public var variables:Map = new Map(); + public var modchartTweens:Map = new Map(); + public var modchartSprites:Map = new Map(); + public var modchartTimers:Map = new Map(); + public var modchartSounds:Map = new Map(); + public var modchartTexts:Map = new Map(); + public var modchartSaves:Map = new Map(); + #end + + public var hitSoundString:String = ClientPrefs.hitsoundType; + + public var BF_X:Float = 770; + public var BF_Y:Float = 100; + public var DAD_X:Float = 100; + public var DAD_Y:Float = 100; + public var GF_X:Float = 400; + public var GF_Y:Float = 130; + + var randomBotplayText:String; + + public var songSpeedTween:FlxTween; + public var songSpeed(default, set):Float = 1; + public var songSpeedType:String = "multiplicative"; + + public var noteKillOffset:Float = 350; + + public var playbackRate(default, set):Float = 1; + + public var boyfriendGroup:FlxSpriteGroup; + public var dadGroup:FlxSpriteGroup; + public var gfGroup:FlxSpriteGroup; + public var shaderUpdates:ArrayVoid> = []; + var botplayUsed:Bool = false; + public static var curStage:String = ''; + public static var isPixelStage:Bool = false; + public static var SONG:SwagSong = null; + public static var isStoryMode:Bool = false; + public static var storyWeek:Int = 0; + public static var storyPlaylist:Array = []; + public static var storyDifficulty:Int = 1; + public var tries:Int = 0; + public var notesLoadedRN:Int = 0; + public var firstNoteStrumTime:Float = 0; + + public var spawnTime:Float = 1800; //just enough for the notes to barely inch off the screen + + public var vocals:FlxSound; + public var dadGhostTween:FlxTween; + public var bfGhostTween:FlxTween; + public var gfGhostTween:FlxTween; + public var dadGhost:FlxSprite; + public var bfGhost:FlxSprite; + public var gfGhost:FlxSprite; + public var dad:Character = null; + public var gf:Character = null; + public var boyfriend:Boyfriend = null; + public static var death:FlxSprite; + public static var deathanim:Bool = false; + public static var dead:Bool = false; + + var tankmanAscend:Bool = false; // funni (2021 nostalgia oh my god) + + public var notes:FlxTypedGroup; + public var unspawnNotes:Array = []; + public var unspawnNotesCopy:Array = []; + public var eventNotes:Array = []; + + private var strumLine:FlxSprite; + + //Handles the new epic mega sexy cam code that i've done + public var camFollow:FlxPoint; + public var camFollowPos:FlxObject; + private static var prevCamFollow:FlxPoint; + private static var prevCamFollowPos:FlxObject; + public var judgeColours:Map = [ + "marv" => 0xFFE367E5, + "sick" => FlxColor.CYAN, + "good" => FlxColor.LIME, + "bad" => FlxColor.ORANGE, + "shit" => FlxColor.RED, + "miss" => 0xFF7F2626 + ]; + public var tgtJudgeColours:Map = [ + "marv" => 0xFFE367E5, + "sick" => 0xFF00A2E8, + "good" => 0xFFB5E61D, + "bad" => 0xFFC3C3C3, + "shit" => 0xFF7F7F7F, + "miss" => 0xFF7F2626, + "cb" => 0xFF7F265A + ]; + + public var strumLineNotes:FlxTypedGroup; + public var opponentStrums:FlxTypedGroup; + public var playerStrums:FlxTypedGroup; + public var grpNoteSplashes:FlxTypedGroup; + public var laneunderlay:FlxSprite; + public var laneunderlayOpponent:FlxSprite; + + public var camZooming:Bool = false; + public var camZoomingMult:Float = 1; + public var camZoomingDecay:Float = 1; + private var curSong:String = ""; + + public var gfSpeed:Int = 1; + public var health:Float; + private var displayedHealth:Float; + public var maxHealth:Float = 2; + + + public var totalNotesPlayed:Float = 0; + public var combo:Float = 0; + public var maxCombo:Float = 0; + public var missCombo:Int = 0; + + public var notesAddedCount:Int = 0; + + var endingTimeLimit:Int = 20; + + var camBopInterval:Int = 4; + var camBopIntensity:Float = 1; + + private var healthBarBG:AttachedSprite; + public var healthBar:FlxBar; + var songPercent:Float = 0; + var songPercentThing:Float = 0; + var playbackRateDecimal:Float = 0; + + private var timeBarBG:AttachedSprite; + public var timeBar:FlxBar; + + public var ratingsData:Array = []; + public var marvs:Int = 0; + public var sicks:Int = 0; + public var goods:Int = 0; + public var bads:Int = 0; + public var shits:Int = 0; + public var nps:Float = 0; + public var maxNPS:Float = 0; + public var oppNPS:Float = 0; + public var maxOppNPS:Float = 0; + public var enemyHits:Float = 0; + public var opponentNoteTotal:Int = 0; + public var polyphony:Float = 1; + public var comboMultiplier:Float = 1; + private var allSicks:Bool = true; + public var stupidIcon1:HealthIcon; + public var stupidIcon2:HealthIcon; + + private var lerpingScore:Bool = false; + + private var generatedMusic:Bool = false; + public var endingSong:Bool = false; + public var startingSong:Bool = false; + private var updateTime:Bool = true; + private var updateThePercent:Bool = true; + public static var changedDifficulty:Bool = false; + public static var chartingMode:Bool = false; + public static var playerIsCheating:Bool = false; //Whether the player is cheating. Enables if you change BOTPLAY or Practice Mode in the Pause menu + + public var shownScore:Float = 0; + + //Gameplay settings + public var healthGain:Float = 1; + public var healthLoss:Float = 1; + public var hpDrainLevel:Float = 1; + public var instakillOnMiss:Bool = false; + public var sickOnly:Bool = false; + public var cpuControlled:Bool = false; + public var practiceMode:Bool = false; + public var opponentDrain:Bool = false; + public static var opponentChart:Bool = false; + public static var bothsides:Bool = false; + var randomMode:Bool = false; + var flip:Bool = false; + var stairs:Bool = false; + var waves:Bool = false; + var oneK:Bool = false; + var randomSpeedThing:Bool = false; + var trollingMode:Bool = false; + public var jackingtime:Float = 0; + + public var songWasLooped:Bool = false; //If the song was looped. Used in Troll Mode + public var shouldKillNotes:Bool = true; //Whether notes should be killed when you hit them. Disables automatically when in Troll Mode because you can't end the song anyway + + public var botplaySine:Float = 0; + public var botplayTxt:FlxText; + public var pauseWarnText:FlxText; + + public var OptimHitText:FlxText; + + public var iconP1:HealthIcon; + public var iconP2:HealthIcon; + public var camHUD:FlxCamera; + public var camGame:FlxCamera; + public var camOther:FlxCamera; + public var cameraSpeed:Float = 1; + var hueh231:FlxSprite; + var secretsong:FlxSprite; + var SPUNCHBOB:FlxSprite; + + public var scoreTxtUpdateFrame:Int = 0; + public var judgeCountUpdateFrame:Int = 0; + public var compactUpdateFrame:Int = 0; + + var notesHitArray:Array = []; + var oppNotesHitArray:Array = []; + var notesHitDateArray:Array = []; + var oppNotesHitDateArray:Array = []; + + var dialogue:Array = ['blah blah blah', 'coolswag']; + var dialogueJson:DialogueFile = null; + + var EngineWatermark:FlxText; + var dadbattleBlack:BGSprite; + var dadbattleLight:BGSprite; + var dadbattleSmokes:FlxSpriteGroup; + + var halloweenBG:BGSprite; + var halloweenWhite:BGSprite; + + var phillyLightsColors:Array; + var phillyWindow:BGSprite; + var phillyStreet:BGSprite; + var phillyTrain:BGSprite; + var blammedLightsBlack:FlxSprite; + var phillyWindowEvent:BGSprite; + var trainSound:FlxSound; + public var compactCombo:String; + public var compactScore:String; + public var compactMisses:String; + public var compactNPS:String; + public var compactMaxCombo:String; + public var compactTotalPlays:String; + + var phillyGlowGradient:PhillyGlow.PhillyGlowGradient; + var phillyGlowParticles:FlxTypedGroup; + + var limoKillingState:Int = 0; + var limo:BGSprite; + var limoMetalPole:BGSprite; + var limoLight:BGSprite; + var limoCorpse:BGSprite; + var limoCorpseTwo:BGSprite; + var bgLimo:BGSprite; + var grpLimoParticles:FlxTypedGroup; + var grpLimoDancers:FlxTypedGroup; + var fastCar:BGSprite; + + var upperBoppers:BGSprite; + var bottomBoppers:BGSprite; + var santa:BGSprite; + var heyTimer:Float; + + var bgGirls:BackgroundGirls; + var wiggleShit:WiggleEffect = new WiggleEffect(); + var bgGhouls:BGSprite; + var softlocked:Bool = false; + + var tankWatchtower:BGSprite; + var tankGround:BGSprite; + var tankmanRun:FlxTypedGroup; + var foregroundSprites:FlxTypedGroup; + + //ms timing popup shit + public var msTxt:FlxText; + public var msTimer:FlxTimer = null; + public var restartTimer:FlxTimer = null; + + public var maxScore:Int = 0; + public var oppScore:Float = 0; + public var songScore:Float = 0; + public var songHits:Int = 0; + public var songMisses:Int = 0; + public var scoreTxt:FlxText; + var comboTxt:FlxText; + var missTxt:FlxText; + var accuracyTxt:FlxText; + var npsTxt:FlxText; + var timeTxt:FlxText; + var timePercentTxt:FlxText; + + var hitTxt:FlxText; + + var scoreTxtTween:FlxTween; + var timeTxtTween:FlxTween; + var judgementCounter:FlxText; + + public static var campaignScore:Float = 0; + public static var campaignMisses:Int = 0; + public static var seenCutscene:Bool = false; + public static var deathCounter:Int = 0; + + public var defaultCamZoom:Float = 1.05; + + // how big to stretch the pixel art assets + public static var daPixelZoom:Float = 6; + public static var sectionsLoaded:Int = 0; + + public var inCutscene:Bool = false; + public var skipCountdown:Bool = false; + var songLength:Float = 0; + + public var boyfriendCameraOffset:Array = null; + public var opponentCameraOffset:Array = null; + public var girlfriendCameraOffset:Array = null; + + #if desktop + // Discord RPC variables + var storyDifficultyText:String = ""; + var detailsText:String = ""; + var detailsPausedText:String = ""; + #end + + //Achievement shit + var keysPressed:Array = []; + var boyfriendIdleTime:Float = 0.0; + var boyfriendIdled:Bool = false; + + // Lua shit + public var luaArray:Array = []; + public var achievementArray:Array = []; + public var achievementWeeks:Array = []; + private var luaDebugGroup:FlxTypedGroup; + public var introSoundsSuffix:String = ''; + + // Debug buttons + private var debugKeysChart:Array; + private var debugKeysCharacter:Array; + + // Less laggy controls + private var keysArray:Array; + private var controlArray:Array; + + var precacheList:Map = new Map(); + + // stores the last judgement object + public static var lastRating:FlxSprite; + // stores the last combo sprite object + public static var lastCombo:FlxSprite; + // stores the last combo score objects in an array + public static var lastScore:Array = []; + + //cam panning + var moveCamTo:HaxeVector = new HaxeVector(2); + + var getTheBotplayText:Int = 0; + + var theListBotplay:Array = []; + + override public function create() + { + var compactCombo:String = formatCompactNumber(combo); + var compactMaxCombo:String = formatCompactNumber(maxCombo); + var compactScore:String = formatCompactNumber(songScore); + var compactMisses:String = formatCompactNumberInt(songMisses); + var compactNPS:String = formatCompactNumber(nps); + var compactTotalPlays:String = formatCompactNumber(totalNotesPlayed); + theListBotplay = CoolUtil.coolTextFile(Paths.txt('botplayText')); + + randomBotplayText = theListBotplay[FlxG.random.int(0, theListBotplay.length - 1)]; + //trace('Playback Rate: ' + playbackRate); + + cpp.vm.Gc.enable(false); //lagspike prevention + + if (!ClientPrefs.memLeaks) + { + Paths.clearStoredMemory(); + + #if sys + openfl.system.System.gc(); + #end + } + + + // for lua + instance = this; + + + if (ClientPrefs.moreMaxHP) + { + maxHealth = 3; + } else + { + maxHealth = 2; + } + + debugKeysChart = ClientPrefs.copyKey(ClientPrefs.keyBinds.get('debug_1')); + debugKeysCharacter = ClientPrefs.copyKey(ClientPrefs.keyBinds.get('debug_2')); + PauseSubState.songName = null; //Reset to default + playbackRate = ClientPrefs.getGameplaySetting('songspeed', 1); + tauntKey = ClientPrefs.copyKey(ClientPrefs.keyBinds.get('qt_taunt')); + + keysArray = [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_left')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_down')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_up')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_right')) + ]; + + controlArray = [ + 'NOTE_LEFT', + 'NOTE_DOWN', + 'NOTE_UP', + 'NOTE_RIGHT' + ]; + + //Ratings + if (!ClientPrefs.noMarvJudge) + { + ratingsData.push(new Rating('marv')); + } + + var rating:Rating = new Rating('sick'); + rating.ratingMod = 1; + rating.score = 350; + rating.noteSplash = true; + ratingsData.push(rating); + + var rating:Rating = new Rating('good'); + rating.ratingMod = 0.7; + rating.score = 200; + rating.noteSplash = false; + ratingsData.push(rating); + + var rating:Rating = new Rating('bad'); + rating.ratingMod = 0.4; + rating.score = 100; + rating.noteSplash = false; + ratingsData.push(rating); + + var rating:Rating = new Rating('shit'); + rating.ratingMod = 0; + rating.score = 50; + rating.noteSplash = false; + ratingsData.push(rating); + + // For the "Just the Two of Us" achievement + for (i in 0...keysArray.length) + { + keysPressed.push(false); + } + + if (FlxG.sound.music != null) + FlxG.sound.music.stop(); + + // Gameplay settings + healthGain = ClientPrefs.getGameplaySetting('healthgain', 1); + healthLoss = ClientPrefs.getGameplaySetting('healthloss', 1); + hpDrainLevel = ClientPrefs.getGameplaySetting('drainlevel', 1); + instakillOnMiss = ClientPrefs.getGameplaySetting('instakill', false); + sickOnly = ClientPrefs.getGameplaySetting('onlySicks', false); + practiceMode = ClientPrefs.getGameplaySetting('practice', false); + cpuControlled = ClientPrefs.getGameplaySetting('botplay', false); + opponentChart = ClientPrefs.getGameplaySetting('opponentplay', false); + bothsides = ClientPrefs.getGameplaySetting('bothSides', false); + trollingMode = ClientPrefs.getGameplaySetting('thetrollingever', false); + opponentDrain = ClientPrefs.getGameplaySetting('opponentdrain', false); + randomMode = ClientPrefs.getGameplaySetting('randommode', false); + flip = ClientPrefs.getGameplaySetting('flip', false); + stairs = ClientPrefs.getGameplaySetting('stairmode', false); + waves = ClientPrefs.getGameplaySetting('wavemode', false); + oneK = ClientPrefs.getGameplaySetting('onekey', false); + randomSpeedThing = ClientPrefs.getGameplaySetting('randomspeed', false); + trollingMode = ClientPrefs.getGameplaySetting('thetrollingever', false); + jackingtime = ClientPrefs.getGameplaySetting('jacks', 0); + + if (trollingMode) + shouldKillNotes = false; + + if (ClientPrefs.showcaseMode) + cpuControlled = true; + + + // var gameCam:FlxCamera = FlxG.camera; + camGame = new FlxCamera(); + camHUD = new FlxCamera(); + camOther = new FlxCamera(); + camHUD.bgColor.alpha = 0; + camOther.bgColor.alpha = 0; + + FlxG.cameras.reset(camGame); + FlxG.cameras.add(camHUD, false); + FlxG.cameras.add(camOther, false); + grpNoteSplashes = new FlxTypedGroup((ClientPrefs.maxSplashLimit != 0 ? ClientPrefs.maxSplashLimit : 10000)); + + FlxG.cameras.setDefaultDrawTarget(camGame, true); + CustomFadeTransition.nextCamera = camOther; + + persistentUpdate = true; + persistentDraw = true; + if (SONG == null) + SONG = Song.loadFromJson('tutorial'); + + Conductor.mapBPMChanges(SONG); + Conductor.changeBPM(SONG.bpm); + + #if desktop + storyDifficultyText = CoolUtil.difficulties[storyDifficulty]; + + // String that contains the mode defined here so it isn't necessary to call changePresence for each mode + if (isStoryMode) + { + detailsText = "Story Mode: " + WeekData.getCurrentWeek().weekName; + } + else + { + detailsText = "Freeplay"; + } + + // String for when the game is paused + detailsPausedText = "BRB! - " + detailsText; + #end + + GameOverSubstate.resetVariables(); + var songName:String = Paths.formatToSongPath(SONG.song); + curStage = (!ClientPrefs.charsAndBG ? "" : SONG.stage); + //trace('stage is: ' + curStage); + if(SONG.stage == null || SONG.stage.length < 1) { + switch (songName) + { + case 'spookeez' | 'south' | 'monster': + curStage = 'spooky'; + case 'pico' | 'blammed' | 'philly' | 'philly-nice': + curStage = 'philly'; + case 'milf' | 'satin-panties' | 'high': + curStage = 'limo'; + case 'cocoa' | 'eggnog': + curStage = 'mall'; + case 'winter-horrorland': + curStage = 'mallEvil'; + case 'senpai' | 'roses': + curStage = 'school'; + case 'thorns': + curStage = 'schoolEvil'; + case 'ugh' | 'guns' | 'stress': + curStage = 'tank'; + default: + curStage = 'stage'; + } + } + SONG.stage = curStage; + + var stageData:StageFile = StageData.getStageFile(curStage); + if(stageData == null) { //Stage couldn't be found, create a dummy stage for preventing a crash + stageData = { + directory: "", + defaultZoom: 0.9, + isPixelStage: false, + + boyfriend: [770, 100], + girlfriend: [400, 130], + opponent: [100, 100], + hide_girlfriend: false, + + camera_boyfriend: [0, 0], + camera_opponent: [0, 0], + camera_girlfriend: [0, 0], + camera_speed: 1 + }; + } + + defaultCamZoom = stageData.defaultZoom; + isPixelStage = stageData.isPixelStage; + BF_X = stageData.boyfriend[0]; + BF_Y = stageData.boyfriend[1]; + GF_X = stageData.girlfriend[0]; + GF_Y = stageData.girlfriend[1]; + DAD_X = stageData.opponent[0]; + DAD_Y = stageData.opponent[1]; + + if(stageData.camera_speed != null) + cameraSpeed = stageData.camera_speed; + + boyfriendCameraOffset = stageData.camera_boyfriend; + if(boyfriendCameraOffset == null) //Fucks sake should have done it since the start :rolling_eyes: + boyfriendCameraOffset = [0, 0]; + + opponentCameraOffset = stageData.camera_opponent; + if(opponentCameraOffset == null) + opponentCameraOffset = [0, 0]; + + girlfriendCameraOffset = stageData.camera_girlfriend; + if(girlfriendCameraOffset == null) + girlfriendCameraOffset = [0, 0]; + + boyfriendGroup = new FlxSpriteGroup(BF_X, BF_Y); + dadGroup = new FlxSpriteGroup(DAD_X, DAD_Y); + gfGroup = new FlxSpriteGroup(GF_X, GF_Y); + + switch (curStage) + { + case 'stage': //Week 1 + var bg:BGSprite = new BGSprite('stageback', -600, -200, 0.9, 0.9); + add(bg); + + var stageFront:BGSprite = new BGSprite('stagefront', -650, 600, 0.9, 0.9); + stageFront.setGraphicSize(Std.int(stageFront.width * 1.1)); + stageFront.updateHitbox(); + add(stageFront); + if(!ClientPrefs.lowQuality) { + var stageLight:BGSprite = new BGSprite('stage_light', -125, -100, 0.9, 0.9); + stageLight.setGraphicSize(Std.int(stageLight.width * 1.1)); + stageLight.updateHitbox(); + add(stageLight); + var stageLight:BGSprite = new BGSprite('stage_light', 1225, -100, 0.9, 0.9); + stageLight.setGraphicSize(Std.int(stageLight.width * 1.1)); + stageLight.updateHitbox(); + stageLight.flipX = true; + add(stageLight); + + var stageCurtains:BGSprite = new BGSprite('stagecurtains', -500, -300, 1.3, 1.3); + stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9)); + stageCurtains.updateHitbox(); + add(stageCurtains); + } + dadbattleSmokes = new FlxSpriteGroup(); //troll'd + + case 'spooky': //Week 2 + if(!ClientPrefs.lowQuality) { + halloweenBG = new BGSprite('halloween_bg', -200, -100, ['halloweem bg0', 'halloweem bg lightning strike']); + } else { + halloweenBG = new BGSprite('halloween_bg_low', -200, -100); + } + add(halloweenBG); + + halloweenWhite = new BGSprite(null, -800, -400, 0, 0); + halloweenWhite.makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.WHITE); + halloweenWhite.alpha = 0; + halloweenWhite.blend = ADD; + + //PRECACHE SOUNDS + precacheList.set('thunder_1', 'sound'); + precacheList.set('thunder_2', 'sound'); + + case 'philly': //Week 3 + if(!ClientPrefs.lowQuality) { + var bg:BGSprite = new BGSprite('philly/sky', -100, 0, 0.1, 0.1); + add(bg); + } + + var city:BGSprite = new BGSprite('philly/city', -10, 0, 0.3, 0.3); + city.setGraphicSize(Std.int(city.width * 0.85)); + city.updateHitbox(); + add(city); + + phillyLightsColors = [0xFF31A2FD, 0xFF31FD8C, 0xFFFB33F5, 0xFFFD4531, 0xFFFBA633]; + phillyWindow = new BGSprite('philly/window', city.x, city.y, 0.3, 0.3); + phillyWindow.setGraphicSize(Std.int(phillyWindow.width * 0.85)); + phillyWindow.updateHitbox(); + add(phillyWindow); + phillyWindow.alpha = 0; + + if(!ClientPrefs.lowQuality) { + var streetBehind:BGSprite = new BGSprite('philly/behindTrain', -40, 50); + add(streetBehind); + } + + phillyTrain = new BGSprite('philly/train', 2000, 360); + add(phillyTrain); + + trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes')); + FlxG.sound.list.add(trainSound); + + phillyStreet = new BGSprite('philly/street', -40, 50); + add(phillyStreet); + + case 'limo': //Week 4 + var skyBG:BGSprite = new BGSprite('limo/limoSunset', -120, -50, 0.1, 0.1); + add(skyBG); + + if(!ClientPrefs.lowQuality) { + limoMetalPole = new BGSprite('gore/metalPole', -500, 220, 0.4, 0.4); + add(limoMetalPole); + + bgLimo = new BGSprite('limo/bgLimo', -150, 480, 0.4, 0.4, ['background limo pink'], true); + add(bgLimo); + + limoCorpse = new BGSprite('gore/noooooo', -500, limoMetalPole.y - 130, 0.4, 0.4, ['Henchmen on rail'], true); + add(limoCorpse); + + limoCorpseTwo = new BGSprite('gore/noooooo', -500, limoMetalPole.y, 0.4, 0.4, ['henchmen death'], true); + add(limoCorpseTwo); + + grpLimoDancers = new FlxTypedGroup(); + add(grpLimoDancers); + + for (i in 0...5) + { + var dancer:BackgroundDancer = new BackgroundDancer((370 * i) + 170, bgLimo.y - 400); + dancer.scrollFactor.set(0.4, 0.4); + grpLimoDancers.add(dancer); + } + + limoLight = new BGSprite('gore/coldHeartKiller', limoMetalPole.x - 180, limoMetalPole.y - 80, 0.4, 0.4); + add(limoLight); + + grpLimoParticles = new FlxTypedGroup(); + add(grpLimoParticles); + + //PRECACHE BLOOD + var particle:BGSprite = new BGSprite('gore/stupidBlood', -400, -400, 0.4, 0.4, ['blood'], false); + particle.alpha = 0.01; + grpLimoParticles.add(particle); + resetLimoKill(); + + //PRECACHE SOUND + precacheList.set('dancerdeath', 'sound'); + } + + limo = new BGSprite('limo/limoDrive', -120, 550, 1, 1, ['Limo stage'], true); + + fastCar = new BGSprite('limo/fastCarLol', -300, 160); + fastCar.active = true; + limoKillingState = 0; + + case 'mall': //Week 5 - Cocoa, Eggnog + var bg:BGSprite = new BGSprite('christmas/bgWalls', -1000, -500, 0.2, 0.2); + bg.setGraphicSize(Std.int(bg.width * 0.8)); + bg.updateHitbox(); + add(bg); + + if(!ClientPrefs.lowQuality) { + upperBoppers = new BGSprite('christmas/upperBop', -240, -90, 0.33, 0.33, ['Upper Crowd Bob']); + upperBoppers.setGraphicSize(Std.int(upperBoppers.width * 0.85)); + upperBoppers.updateHitbox(); + add(upperBoppers); + + var bgEscalator:BGSprite = new BGSprite('christmas/bgEscalator', -1100, -600, 0.3, 0.3); + bgEscalator.setGraphicSize(Std.int(bgEscalator.width * 0.9)); + bgEscalator.updateHitbox(); + add(bgEscalator); + } + + var tree:BGSprite = new BGSprite('christmas/christmasTree', 370, -250, 0.40, 0.40); + add(tree); + + bottomBoppers = new BGSprite('christmas/bottomBop', -300, 140, 0.9, 0.9, ['Bottom Level Boppers Idle']); + bottomBoppers.animation.addByPrefix('hey', 'Bottom Level Boppers HEY', 24, false); + bottomBoppers.setGraphicSize(Std.int(bottomBoppers.width * 1)); + bottomBoppers.updateHitbox(); + add(bottomBoppers); + + var fgSnow:BGSprite = new BGSprite('christmas/fgSnow', -600, 700); + add(fgSnow); + + santa = new BGSprite('christmas/santa', -840, 150, 1, 1, ['santa idle in fear']); + add(santa); + precacheList.set('Lights_Shut_off', 'sound'); + + case 'mallEvil': //Week 5 - Winter Horrorland + var bg:BGSprite = new BGSprite('christmas/evilBG', -400, -500, 0.2, 0.2); + bg.setGraphicSize(Std.int(bg.width * 0.8)); + bg.updateHitbox(); + add(bg); + + var evilTree:BGSprite = new BGSprite('christmas/evilTree', 300, -300, 0.2, 0.2); + add(evilTree); + + var evilSnow:BGSprite = new BGSprite('christmas/evilSnow', -200, 700); + add(evilSnow); + + case 'school': //Week 6 - Senpai, Roses + GameOverSubstate.deathSoundName = 'fnf_loss_sfx-pixel'; + GameOverSubstate.loopSoundName = 'gameOver-pixel'; + GameOverSubstate.endSoundName = 'gameOverEnd-pixel'; + GameOverSubstate.characterName = 'bf-pixel-dead'; + + var bgSky:BGSprite = new BGSprite('weeb/weebSky', 0, 0, 0.1, 0.1); + add(bgSky); + bgSky.antialiasing = false; + + var repositionShit = -200; + + var bgSchool:BGSprite = new BGSprite('weeb/weebSchool', repositionShit, 0, 0.6, 0.90); + add(bgSchool); + bgSchool.antialiasing = false; + + var bgStreet:BGSprite = new BGSprite('weeb/weebStreet', repositionShit, 0, 0.95, 0.95); + add(bgStreet); + bgStreet.antialiasing = false; + + var widShit = Std.int(bgSky.width * 6); + if(!ClientPrefs.lowQuality) { + var fgTrees:BGSprite = new BGSprite('weeb/weebTreesBack', repositionShit + 170, 130, 0.9, 0.9); + fgTrees.setGraphicSize(Std.int(widShit * 0.8)); + fgTrees.updateHitbox(); + add(fgTrees); + fgTrees.antialiasing = false; + } + + var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800); + bgTrees.frames = Paths.getPackerAtlas('weeb/weebTrees'); + 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); + bgTrees.antialiasing = false; + + if(!ClientPrefs.lowQuality) { + var treeLeaves:BGSprite = new BGSprite('weeb/petals', repositionShit, -40, 0.85, 0.85, ['PETALS ALL'], true); + treeLeaves.setGraphicSize(widShit); + treeLeaves.updateHitbox(); + add(treeLeaves); + treeLeaves.antialiasing = false; + } + + bgSky.setGraphicSize(widShit); + bgSchool.setGraphicSize(widShit); + bgStreet.setGraphicSize(widShit); + bgTrees.setGraphicSize(Std.int(widShit * 1.4)); + + bgSky.updateHitbox(); + bgSchool.updateHitbox(); + bgStreet.updateHitbox(); + bgTrees.updateHitbox(); + + if(!ClientPrefs.lowQuality) { + bgGirls = new BackgroundGirls(-100, 190); + bgGirls.scrollFactor.set(0.9, 0.9); + + bgGirls.setGraphicSize(Std.int(bgGirls.width * daPixelZoom)); + bgGirls.updateHitbox(); + add(bgGirls); + } + + case 'schoolEvil': //Week 6 - Thorns + GameOverSubstate.deathSoundName = 'fnf_loss_sfx-pixel'; + GameOverSubstate.loopSoundName = 'gameOver-pixel'; + GameOverSubstate.endSoundName = 'gameOverEnd-pixel'; + GameOverSubstate.characterName = 'bf-pixel-dead'; + + /*if(!ClientPrefs.lowQuality) { //Does this even do something? + 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; + if(!ClientPrefs.lowQuality) { + var bg:BGSprite = new BGSprite('weeb/animatedEvilSchool', posX, posY, 0.8, 0.9, ['background 2'], true); + bg.scale.set(6, 6); + bg.antialiasing = false; + add(bg); + + bgGhouls = new BGSprite('weeb/bgGhouls', -100, 190, 0.9, 0.9, ['BG freaks glitch instance'], false); + bgGhouls.setGraphicSize(Std.int(bgGhouls.width * daPixelZoom)); + bgGhouls.updateHitbox(); + bgGhouls.visible = false; + bgGhouls.antialiasing = false; + add(bgGhouls); + } else { + var bg:BGSprite = new BGSprite('weeb/animatedEvilSchool_low', posX, posY, 0.8, 0.9); + bg.scale.set(6, 6); + bg.antialiasing = false; + add(bg); + } + + case 'tank': //Week 7 - Ugh, Guns, Stress + var sky:BGSprite = new BGSprite('tankSky', -400, -400, 0, 0); + add(sky); + + if(!ClientPrefs.lowQuality) + { + var clouds:BGSprite = new BGSprite('tankClouds', FlxG.random.int(-700, -100), FlxG.random.int(-20, 20), 0.1, 0.1); + clouds.active = true; + clouds.velocity.x = FlxG.random.float(5, 15); + add(clouds); + + var mountains:BGSprite = new BGSprite('tankMountains', -300, -20, 0.2, 0.2); + mountains.setGraphicSize(Std.int(1.2 * mountains.width)); + mountains.updateHitbox(); + add(mountains); + + var buildings:BGSprite = new BGSprite('tankBuildings', -200, 0, 0.3, 0.3); + buildings.setGraphicSize(Std.int(1.1 * buildings.width)); + buildings.updateHitbox(); + add(buildings); + } + + var ruins:BGSprite = new BGSprite('tankRuins',-200,0,.35,.35); + ruins.setGraphicSize(Std.int(1.1 * ruins.width)); + ruins.updateHitbox(); + add(ruins); + + if(!ClientPrefs.lowQuality) + { + var smokeLeft:BGSprite = new BGSprite('smokeLeft', -200, -100, 0.4, 0.4, ['SmokeBlurLeft'], true); + add(smokeLeft); + var smokeRight:BGSprite = new BGSprite('smokeRight', 1100, -100, 0.4, 0.4, ['SmokeRight'], true); + add(smokeRight); + + tankWatchtower = new BGSprite('tankWatchtower', 100, 50, 0.5, 0.5, ['watchtower gradient color']); + add(tankWatchtower); + } + + tankGround = new BGSprite('tankRolling', 300, 300, 0.5, 0.5,['BG tank w lighting'], true); + add(tankGround); + + tankmanRun = new FlxTypedGroup(); + add(tankmanRun); + + var ground:BGSprite = new BGSprite('tankGround', -420, -150); + ground.setGraphicSize(Std.int(1.15 * ground.width)); + ground.updateHitbox(); + add(ground); + moveTank(); + + foregroundSprites = new FlxTypedGroup(); + foregroundSprites.add(new BGSprite('tank0', -500, 650, 1.7, 1.5, ['fg'])); + if(!ClientPrefs.lowQuality) foregroundSprites.add(new BGSprite('tank1', -300, 750, 2, 0.2, ['fg'])); + foregroundSprites.add(new BGSprite('tank2', 450, 940, 1.5, 1.5, ['foreground'])); + if(!ClientPrefs.lowQuality) foregroundSprites.add(new BGSprite('tank4', 1300, 900, 1.5, 1.5, ['fg'])); + foregroundSprites.add(new BGSprite('tank5', 1620, 700, 1.5, 1.5, ['fg'])); + if(!ClientPrefs.lowQuality) foregroundSprites.add(new BGSprite('tank3', 1300, 1200, 3.5, 2.5, ['fg'])); + } + + switch(Paths.formatToSongPath(SONG.song)) + { + case 'stress': + GameOverSubstate.characterName = 'bf-holding-gf-dead'; + } + + if(isPixelStage) { + introSoundsSuffix = '-pixel'; + } + + dadGhost = new FlxSprite(); + bfGhost = new FlxSprite(); + gfGhost = new FlxSprite(); + add(gfGroup); //Needed for blammed lights + if (ClientPrefs.doubleGhost) + { + add(bfGhost); + add(gfGhost); + add(dadGhost); + } + + // Shitty layering but whatev it works LOL + if (curStage == 'limo') + add(limo); + + add(dadGroup); + add(boyfriendGroup); + + switch(curStage) + { + case 'spooky': + add(halloweenWhite); + case 'tank': + add(foregroundSprites); + } + + #if LUA_ALLOWED + luaDebugGroup = new FlxTypedGroup(); + luaDebugGroup.cameras = [camOther]; + add(luaDebugGroup); + #end + + // "GLOBAL" SCRIPTS + #if LUA_ALLOWED + var filesPushed:Array = []; + var foldersToCheck:Array = [SUtil.getPath() + Paths.getPreloadPath('scripts/')]; + + #if MODS_ALLOWED + foldersToCheck.insert(0, Paths.mods('scripts/')); + if(Paths.currentModDirectory != null && Paths.currentModDirectory.length > 0) + foldersToCheck.insert(0, Paths.mods(Paths.currentModDirectory + '/scripts/')); + + for(mod in Paths.getGlobalMods()) + foldersToCheck.insert(0, Paths.mods(mod + '/scripts/')); + #end + + for (folder in foldersToCheck) + { + if(FileSystem.exists(folder)) + { + for (file in FileSystem.readDirectory(folder)) + { + if(file.endsWith('.lua') && !filesPushed.contains(file)) + { + luaArray.push(new FunkinLua(folder + file)); + filesPushed.push(file); + } + } + } + } + #end + + + //CUSTOM ACHIVEMENTS + #if (MODS_ALLOWED && LUA_ALLOWED && ACHIEVEMENTS_ALLOWED) + var luaFiles:Array = Achievements.getModAchievements().copy(); + if(luaFiles.length > 0){ + for(luaFile in luaFiles) + { + var lua = new FunkinLua(luaFile); + luaArray.push(lua); + achievementArray.push(lua); + } + } + + var achievementMetas = Achievements.getModAchievementMetas().copy(); + for (i in achievementMetas) { + if(i.lua_code != null) { + var lua = new FunkinLua(null, i.lua_code); + luaArray.push(lua); + achievementArray.push(lua); + } + if(i.week_nomiss != null) { + achievementWeeks.push(i.week_nomiss); + } + } + #end + + // STAGE SCRIPTS + #if (MODS_ALLOWED && LUA_ALLOWED) + startLuasOnFolder('stages/' + curStage + '.lua'); + #end + if(ClientPrefs.communityGameMode) + { + SONG.gfVersion = 'gf-bent'; + trace('using the suspicious gf skin, horny ass mf.'); + } + var gfVersion:String = SONG.gfVersion; + + if(gfVersion == null || gfVersion.length < 1) + { + switch (curStage) + { + case 'limo': + gfVersion = 'gf-car'; + case 'mall' | 'mallEvil': + gfVersion = 'gf-christmas'; + case 'school' | 'schoolEvil': + gfVersion = 'gf-pixel'; + case 'tank': + gfVersion = 'gf-tankmen'; + default: + gfVersion = 'gf'; + } + + + switch(Paths.formatToSongPath(SONG.song)) + { + case 'stress': + gfVersion = 'pico-speaker'; + } + SONG.gfVersion = gfVersion; //Fix for the Chart Editor + + } + health = maxHealth / 2; + displayedHealth = maxHealth / 2; + + if (!stageData.hide_girlfriend && ClientPrefs.charsAndBG) + { + gf = new Character(0, 0, gfVersion); + startCharacterPos(gf); + gf.scrollFactor.set(0.95, 0.95); + gfGroup.add(gf); + startCharacterLua(gf.curCharacter); + + if(gfVersion == 'pico-speaker') + { + if(!ClientPrefs.lowQuality) + { + var firstTank:TankmenBG = new TankmenBG(20, 500, true); + firstTank.resetShit(20, 600, true); + firstTank.strumTime = 10; + tankmanRun.add(firstTank); + + for (i in 0...TankmenBG.animationNotes.length) + { + if(FlxG.random.bool(16)) { + var tankBih = tankmanRun.recycle(TankmenBG); + tankBih.strumTime = TankmenBG.animationNotes[i][0]; + tankBih.resetShit(500, 200 + FlxG.random.int(50, 100), TankmenBG.animationNotes[i][1] < 2); + tankmanRun.add(tankBih); + } + } + } + } + } + + if (ClientPrefs.rateNameStuff == 'Quotes') + { + ratingStuff = [ + ['you suck ass lol', 0.2], //From 0% to 19% + ['you aint doin good', 0.4], //From 20% to 39% + ['Bad', 0.5], //From 40% to 49% + ['Bruh', 0.6], //From 50% to 59% + ['Meh', 0.69], //From 60% to 68% + ['funny number', 0.69417], //69.0% to 69.419% ( ͡° ͜ʖ ͡°) + ['( ͡° ͜ʖ ͡°)', 0.6943], //69.420% ( ͡° ͜ʖ ͡°) + ['funny number', 0.7], //69.421% to 69.999% ( ͡° ͜ʖ ͡°) + ['nice', 0.8], //From 70% to 79% + ['awesome', 0.9], //From 80% to 89% + ['thats amazing', 1], //From 90% to 99% + ['PERFECT!!!!!!', 1] //The value on this one isn't used actually, since Perfect is always "1" + ]; + } + if (ClientPrefs.rateNameStuff == 'Psych Quotes') + { + ratingStuff = [ + ['How are you this bad?', 0.1], //From 0% to 9% + ['You Suck!', 0.2], //From 10% to 19% + ['Horribly Shit', 0.3], //From 20% to 29% + ['Shit', 0.4], //From 30% to 39% + ['Bad', 0.5], //From 40% to 49% + ['Bruh', 0.6], //From 50% to 59% + ['Meh', 0.69], //From 60% to 68% + ['Nice', 0.7], //69% + ['Good', 0.8], //From 70% to 79% + ['Great', 0.9], //From 80% to 89% + ['Sick!', 1], //From 90% to 99% + ['Perfect!!', 1] //The value on this one isn't used actually, since Perfect is always "1" + ]; + } + if (ClientPrefs.rateNameStuff == 'Shaggyverse Quotes') + { + ratingStuff = [ + ['G - Ruh Rouh!', 0.2], //From 0% to 19% + ['F - OOF', 0.4], //From 20% to 39% + ["E - Like, You're Bad", 0.5], //From 40% to 49% + ['D - Like, how are you still alive?', 0.6], //From 50% to 59% + ['C - ZOINKS!', 0.69], //From 60% to 68% + ["Nice - WOW, that's a funny number man!", 0.7], //69% + ["B - That's like, really cool...", 0.75], //From 70% to 74% + ["B+ - Hey, man, you're starting to improve!", 0.8], //From 75% to 79% + ['A - This is a challenge!', 0.85], //From 80% to 84% + ['AA - Hey Scoob, This kid is good!', 0.9], //From 85% to 90% + ['S - Like, Thats Good', 0.95], //From 90% to 94% + ['SS - Like, Thats Great!', 0.99], //From 95% to 98% + ['SSS - Like, Thats Sick!', 1], //99% + ['SSSS - Like, WOW', 1] //The value on this one isn't used actually, since Perfect is always "1" + ]; + } + if (ClientPrefs.rateNameStuff == 'Letters') + { + ratingStuff = [ + ['HOW?', 0.2], //From 0% to 19% + ['F', 0.4], //From 20% to 39% + ['E', 0.5], //From 40% to 49% + ['D', 0.6], //From 50% to 59% + ['C', 0.69], //From 60% to 68% + ['FUNNY', 0.7], //69% + ['B', 0.8], //From 70% to 79% + ['A', 0.9], //From 80% to 89% + ['S', 0.97], //From 90% to 98% + ['S+', 1], //98% to 99% + ['X', 1] //The value on this one isn't used actually, since Perfect is always "1" + ]; + } + if (!ClientPrefs.charsAndBG) + { + dad = new Character(0, 0, ""); + dadGroup.add(dad); + + boyfriend = new Boyfriend(0, 0, ""); + boyfriendGroup.add(boyfriend); + } else + { + dad = new Character(0, 0, SONG.player2); + startCharacterPos(dad, true); + dadGroup.add(dad); + startCharacterLua(dad.curCharacter); + + boyfriend = new Boyfriend(0, 0, SONG.player1); + startCharacterPos(boyfriend); + boyfriendGroup.add(boyfriend); + startCharacterLua(boyfriend.curCharacter); + } + if (ClientPrefs.doubleGhost || ClientPrefs.charsAndBG) + { + dadGhost.visible = false; + dadGhost.antialiasing = true; + dadGhost.scale.copyFrom(dad.scale); + dadGhost.updateHitbox(); + bfGhost.visible = false; + bfGhost.antialiasing = true; + bfGhost.scale.copyFrom(boyfriend.scale); + bfGhost.updateHitbox(); + if (!stageData.hide_girlfriend || ClientPrefs.charsAndBG && !stageData.hide_girlfriend) { //stops crashes if the stage data specifies to hide gf + gfGhost.visible = false; + gfGhost.antialiasing = true; + gfGhost.scale.copyFrom(gf.scale); + gfGhost.updateHitbox(); + } + } + + var camPos:FlxPoint = new FlxPoint(girlfriendCameraOffset[0], girlfriendCameraOffset[1]); + if(gf != null) + { + camPos.x += gf.getGraphicMidpoint().x + gf.cameraPosition[0]; + camPos.y += gf.getGraphicMidpoint().y + gf.cameraPosition[1]; + } + + if(dad.curCharacter.startsWith('gf')) { + dad.setPosition(GF_X, GF_Y); + if(gf != null) + gf.visible = false; + } + + switch(curStage) + { + case 'limo': + resetFastCar(); + addBehindGF(fastCar); + + case 'schoolEvil': + var evilTrail = new FlxTrail(dad, null, 4, 24, 0.3, 0.069); //nice + addBehindDad(evilTrail); + } + + var file:String = Paths.json(songName + '/dialogue'); //Checks for json/Psych Engine dialogue + if (OpenFlAssets.exists(file)) { + dialogueJson = DialogueBoxPsych.parseDialogue(SUtil.getPath() + file); + } + + var file:String = Paths.txt(songName + '/' + songName + 'Dialogue'); //Checks for vanilla/Senpai dialogue + if (OpenFlAssets.exists(file)) { + dialogue = CoolUtil.coolTextFile(SUtil.getPath() + file); + } + var doof:DialogueBox = new DialogueBox(false, dialogue); + // doof.x += 70; + // doof.y = FlxG.height * 0.5; + doof.scrollFactor.set(); + doof.finishThing = startCountdown; + doof.nextDialogueThing = startNextDialogue; + doof.skipDialogueThing = skipDialogue; + + Conductor.songPosition = -5000 / Conductor.songPosition; + + laneunderlayOpponent = new FlxSprite(70, 0).makeGraphic(500, FlxG.height * 2, FlxColor.BLACK); + laneunderlayOpponent.alpha = ClientPrefs.laneUnderlayAlpha; + laneunderlayOpponent.scrollFactor.set(); + laneunderlayOpponent.screenCenter(Y); + laneunderlayOpponent.visible = ClientPrefs.laneUnderlay; + + laneunderlay = new FlxSprite(70 + (FlxG.width / 2), 0).makeGraphic(500, FlxG.height * 2, FlxColor.BLACK); + laneunderlay.alpha = ClientPrefs.laneUnderlayAlpha; + laneunderlay.scrollFactor.set(); + laneunderlay.screenCenter(Y); + laneunderlay.visible = ClientPrefs.laneUnderlay; + + if (ClientPrefs.laneUnderlay) + { + add(laneunderlayOpponent); + add(laneunderlay); + } + + strumLine = new FlxSprite(ClientPrefs.middleScroll ? STRUM_X_MIDDLESCROLL : STRUM_X, 50).makeGraphic(FlxG.width, 10); + if(ClientPrefs.downScroll) strumLine.y = FlxG.height - 150; + strumLine.scrollFactor.set(); + + var showTime:Bool = (ClientPrefs.timeBarType != 'Disabled'); + + if (ClientPrefs.hudType == 'Psych Engine') { + timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); + timeTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.scrollFactor.set(); + timeTxt.alpha = 0; + timeTxt.borderSize = 2; + timeTxt.visible = showTime; + if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; + } + if (ClientPrefs.hudType == 'Leather Engine') { + timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); + timeTxt.setFormat(Paths.font("vcr.ttf"), 18, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.scrollFactor.set(); + timeTxt.alpha = 0; + timeTxt.borderSize = 2; + timeTxt.visible = showTime; + if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; + } + if (ClientPrefs.hudType == 'JS Engine') { + timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 20); + timeTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.scrollFactor.set(); + timeTxt.alpha = 0; + timeTxt.borderSize = 3; + timeTxt.visible = showTime; + if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; + } + if (ClientPrefs.hudType == 'Tails Gets Trolled V4') { + timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); + timeTxt.setFormat(Paths.font("calibri.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.scrollFactor.set(); + timeTxt.alpha = 0; + timeTxt.borderSize = 2; + timeTxt.visible = showTime; + if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; + } + if (ClientPrefs.hudType == 'Kade Engine') { + timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 18); + timeTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.scrollFactor.set(); + timeTxt.alpha = 0; + timeTxt.borderSize = 1; + timeTxt.visible = showTime; + if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; + } + if (ClientPrefs.hudType == 'Dave and Bambi') { + timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); + timeTxt.setFormat(Paths.font("comic.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.scrollFactor.set(); + timeTxt.alpha = 0; + timeTxt.borderSize = 2; + timeTxt.visible = showTime; + if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; + } + if (ClientPrefs.hudType == 'Doki Doki+') { + timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 32); + timeTxt.setFormat(Paths.font("Aller_rg.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.scrollFactor.set(); + timeTxt.alpha = 0; + timeTxt.borderSize = 2; + timeTxt.visible = showTime; + if(ClientPrefs.downScroll) timeTxt.y = FlxG.height - 44; + } + if (ClientPrefs.hudType == 'VS Impostor') { + timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 585, 20, 400, "", 32); + timeTxt.setFormat(Paths.font("vcr.ttf"), 14, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.scrollFactor.set(); + timeTxt.alpha = 0; + timeTxt.borderSize = 1; + timeTxt.visible = showTime; + if (ClientPrefs.downScroll) timeTxt.y = FlxG.height - 45; + } + if (ClientPrefs.hudType == "Mic'd Up") { + timeTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 19, 400, "", 16); + if (ClientPrefs.downScroll) + timeTxt.y = FlxG.height - 44; + timeTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.scrollFactor.set(); + timeTxt.screenCenter(X); + timeTxt.visible = showTime; + } + + + if(ClientPrefs.timeBarType == 'Song Name' && !ClientPrefs.timebarShowSpeed) + { + timeTxt.text = SONG.song; + } + updateTime = showTime; + + if (ClientPrefs.hudType == 'VS Impostor') { + timeBarBG = new AttachedSprite('impostorTimeBar'); + timeBarBG.x = timeTxt.x; + timeBarBG.y = timeTxt.y + (timeTxt.height / 4); + timeBarBG.scrollFactor.set(); + timeBarBG.alpha = 0; + timeBarBG.visible = showTime; + // timeBarBG.color = FlxColor.BLACK; + timeBarBG.antialiasing = false; + timeBarBG.xAdd = -4; + timeBarBG.yAdd = -4; + add(timeBarBG); + + + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.createFilledBar(0xFF2e412e, 0xFF44d844); + timeBar.numDivisions = 800; // How much lag this causes?? Should i tone it down to idk, 400 or 200? + timeBar.alpha = 0; + timeBar.visible = showTime; + add(timeBar); + add(timeTxt); + timeBarBG.sprTracker = timeBar; + timeTxt.x += 10; + timeTxt.y += 4; + } + + if (ClientPrefs.hudType == 'Psych Engine') { + timeBarBG = new AttachedSprite('timeBar'); + timeBarBG.x = timeTxt.x; + timeBarBG.y = timeTxt.y + (timeTxt.height / 4); + timeBarBG.scrollFactor.set(); + timeBarBG.alpha = 0; + timeBarBG.visible = showTime; + timeBarBG.color = FlxColor.BLACK; + timeBarBG.xAdd = -4; + timeBarBG.yAdd = -4; + add(timeBarBG); + + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.createFilledBar(0xFF000000, 0xFFFFFFFF); + timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? + timeBar.alpha = 0; + timeBar.visible = showTime; + add(timeBar); + add(timeTxt); + timeBarBG.sprTracker = timeBar; + } + if (ClientPrefs.hudType == 'Leather Engine') { + timeBarBG = new AttachedSprite('healthBar'); + timeBarBG.x = timeTxt.x; + timeBarBG.y = timeTxt.y + (timeTxt.height / 8); + timeBarBG.scrollFactor.set(); + timeBarBG.alpha = 0; + timeBarBG.visible = showTime; + timeBarBG.color = FlxColor.BLACK; + timeBarBG.xAdd = -4; + timeBarBG.yAdd = -4; + timeBarBG.screenCenter(X); + add(timeBarBG); + + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.createFilledBar(FlxColor.BLACK, FlxColor.WHITE); + timeBar.numDivisions = 400; + timeBar.alpha = 0; + timeBar.visible = showTime; + add(timeBar); + add(timeTxt); + } + if (ClientPrefs.hudType == 'Tails Gets Trolled V4') { + timeBarBG = new AttachedSprite('timeBar'); + timeBarBG.x = timeTxt.x; + timeBarBG.y = timeTxt.y + (timeTxt.height / 4); + timeBarBG.scrollFactor.set(); + timeBarBG.alpha = 0; + timeBarBG.visible = showTime; + timeBarBG.color = FlxColor.BLACK; + timeBarBG.xAdd = -4; + timeBarBG.yAdd = -4; + add(timeBarBG); + + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.createFilledBar(0xFF000000, 0xFFFFFFFF); + timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? + timeBar.alpha = 0; + timeBar.visible = showTime; + add(timeBar); + add(timeTxt); + timeBarBG.sprTracker = timeBar; + } + if (ClientPrefs.hudType == 'Box Funkin') { + timeBarBG = new AttachedSprite('WITimeBar'); + timeBarBG.y = 695; + if (ClientPrefs.downScroll) timeBarBG.y = 3; + timeBarBG.scrollFactor.set(); + timeBarBG.updateHitbox(); + timeBarBG.screenCenter(X); + timeBarBG.alpha = 0; + add(timeBarBG); + timeBarBG.xAdd = -12; + timeBarBG.yAdd = -4; + timeBarBG.screenCenter(X); + timeBarBG.color = FlxColor.BLACK; + + timeTxt = new FlxText(0, (ClientPrefs.downScroll ? timeBarBG.y + 32 : timeBarBG.y - 32), 400, "", 20); + timeTxt.setFormat(Paths.font("MilkyNice.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timeTxt.alpha = 0; + timeTxt.borderSize = 3; + timeTxt.screenCenter(X); + timeTxt.antialiasing = ClientPrefs.globalAntialiasing; + updateTime = true; + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 5, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 24), Std.int(timeBarBG.height - 8), this, 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.createFilledBar(0xFF000000, 0xFFFFFFFF); + timeBar.numDivisions = 800; // How much lag this causes?? Should i tone it down to idk, 400 or 200? + timeBar.alpha = 0; + timeBarBG.xAdd = -12; + timeBar.screenCenter(X); + add(timeBar); + add(timeTxt); + timeBarBG.sprTracker = timeBar; + } + + if (ClientPrefs.hudType == 'Kade Engine') { + timeBarBG = new AttachedSprite('healthBar'); + timeBarBG.x = timeTxt.x; + timeBarBG.y = timeTxt.y + (timeTxt.height / 8); + timeBarBG.scrollFactor.set(); + timeBarBG.alpha = 0; + timeBarBG.visible = showTime; + timeBarBG.color = FlxColor.BLACK; + timeBarBG.xAdd = -4; + timeBarBG.yAdd = -4; + timeBarBG.screenCenter(X); + add(timeBarBG); + + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); + timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? + timeBar.alpha = 0; + timeBar.visible = showTime; + add(timeBar); + add(timeTxt); + timeBarBG.sprTracker = timeBar; + } + + if (ClientPrefs.hudType == "Mic'd Up") { + timeBarBG = new AttachedSprite('healthBar'); + timeBarBG.x = timeTxt.x; + timeBarBG.y = timeTxt.y + (timeTxt.height / 8); + timeBarBG.scrollFactor.set(); + timeBarBG.alpha = 0; + timeBarBG.visible = showTime; + timeBarBG.color = FlxColor.BLACK; + timeBarBG.xAdd = -4; + timeBarBG.yAdd = -4; + timeBarBG.screenCenter(X); + add(timeBarBG); + + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); + timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? + timeBar.alpha = 0; + timeBar.visible = showTime; + add(timeBar); + timeBarBG.sprTracker = timeBar; + add(timeTxt); + } + + if (ClientPrefs.hudType == 'Dave and Bambi') { + timeBarBG = new AttachedSprite('DnBTimeBar'); + timeBarBG.screenCenter(X); + timeBarBG.y = timeTxt.y + (timeTxt.height / 4); + timeBarBG.antialiasing = true; + timeBarBG.scrollFactor.set(); + timeBarBG.visible = showTime; + timeBarBG.xAdd = -4; + timeBarBG.yAdd = -4; + add(timeBarBG); + + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? + timeBar.alpha = 0; + timeBar.visible = showTime; + add(timeTxt); + timeBarBG.sprTracker = timeBar; + timeBar.createFilledBar(FlxColor.GRAY, FlxColor.fromRGB(57, 255, 20)); + insert(members.indexOf(timeBarBG), timeBar); + } + if (ClientPrefs.hudType == 'Doki Doki+') { + timeBarBG = new AttachedSprite('dokiTimeBar'); + timeBarBG.screenCenter(X); + timeBarBG.y = timeTxt.y + (timeTxt.height / 4); + timeBarBG.antialiasing = true; + timeBarBG.scrollFactor.set(); + timeBarBG.visible = showTime; + timeBarBG.xAdd = -4; + timeBarBG.yAdd = -4; + add(timeBarBG); + + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.numDivisions = 800; //How much lag this causes?? Should i tone it down to idk, 400 or 200? + timeBar.alpha = 0; + timeBar.visible = showTime; + timeBarBG.sprTracker = timeBar; + timeBar.createGradientBar([FlxColor.TRANSPARENT], [FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2])]); + add(timeBar); + add(timeTxt); + } + if (ClientPrefs.hudType == 'JS Engine') { + timeBarBG = new AttachedSprite('healthBar'); + timeBarBG.screenCenter(X); + timeBarBG.x = timeTxt.x; + timeBarBG.y = timeTxt.y + (timeTxt.height / 8); + timeBarBG.scrollFactor.set(); + timeBarBG.alpha = 0; + timeBarBG.visible = showTime; + timeBarBG.color = FlxColor.BLACK; + timeBarBG.xAdd = -4; + timeBarBG.yAdd = -4; + timeBarBG.screenCenter(X); + add(timeBarBG); + + timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + 'songPercent', 0, 1); + timeBar.scrollFactor.set(); + timeBar.numDivisions = 1000; //How much lag this causes?? Should i tone it down to idk, 400 or 200? + timeBar.alpha = 0; + timeBar.visible = showTime; + timeBarBG.sprTracker = timeBar; + timeBar.createGradientBar([FlxColor.TRANSPARENT], [FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2]), FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])]); + add(timeBar); + add(timeTxt); + } + timePercentTxt = new FlxText(800, 19, 400, "", 32); + if (ClientPrefs.hudType == 'Doki Doki+') timePercentTxt.setFormat(Paths.font("Aller_rg.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + if (ClientPrefs.hudType == 'Tails Gets Trolled V4') timePercentTxt.setFormat(Paths.font("calibri.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + if (ClientPrefs.hudType == 'Dave and Bambi') timePercentTxt.setFormat(Paths.font("comic.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + if (ClientPrefs.hudType != 'Dave and Bambi' && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') timePercentTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + timePercentTxt.scrollFactor.set(); + timePercentTxt.alpha = 0; + timePercentTxt.borderSize = 2; + timePercentTxt.visible = ClientPrefs.songPercentage; + updateThePercent = ClientPrefs.songPercentage; + if(ClientPrefs.downScroll) timePercentTxt.y = FlxG.height - 44; + if (ClientPrefs.timeBarType == 'Disabled') timePercentTxt.screenCenter(X); + if (ClientPrefs.hudType == 'Kade Engine' && ClientPrefs.hudType == 'Dave and Bambi') timePercentTxt.x = timeBarBG.x + 600; + add(timePercentTxt); + + strumLineNotes = new FlxTypedGroup(); + add(strumLineNotes); + add(grpNoteSplashes); + + + if(ClientPrefs.timeBarType == 'Song Name' && ClientPrefs.hudType == 'VS Impostor') + { + timeTxt.size = 14; + } + + var splash:NoteSplash = new NoteSplash(100, 100, 0); + grpNoteSplashes.add(splash); + splash.alpha = 0.0; + + playerStrums = new FlxTypedGroup(); + opponentStrums = new FlxTypedGroup(); + + // startCountdown(); + trace ('Loading chart...'); + generateSong(SONG.song); + + if (curSong.toLowerCase() == "guns") // added this to bring back the old 2021 fnf vibes, i wish the fnf fandom revives one day :( + { + var randomVar:Int = 0; + if (!ClientPrefs.noGunsRNG) randomVar = Std.random(15); + if (ClientPrefs.noGunsRNG) randomVar = 8; + trace(randomVar); + if (randomVar == 8) + { + trace('AWW YEAH, ITS ASCENDING TIME'); + tankmanAscend = true; + } + } + + // After all characters being loaded, it makes then invisible 0.01s later so that the player won't freeze when you change characters + // add(strumLine); + + if (unspawnNotes[0] != null) firstNoteStrumTime = unspawnNotes[0].strumTime; + + camFollow = new FlxPoint(); + camFollowPos = new FlxObject(0, 0, 1, 1); + + snapCamFollowToPos(camPos.x, camPos.y); + if (prevCamFollow != null) + { + camFollow = prevCamFollow; + prevCamFollow = null; + } + if (prevCamFollowPos != null) + { + camFollowPos = prevCamFollowPos; + prevCamFollowPos = null; + } + add(camFollowPos); + if (!ClientPrefs.charsAndBG) FlxG.camera.zoom = 100; //zoom it in very big to avoid high RAM usage!! + if (ClientPrefs.charsAndBG) + { + FlxG.camera.follow(camFollowPos, LOCKON, 1); + // FlxG.camera.setScrollBounds(0, FlxG.width, 0, FlxG.height); + FlxG.camera.zoom = defaultCamZoom; + FlxG.camera.focusOn(camFollow); + + FlxG.worldBounds.set(0, 0, FlxG.width, FlxG.height); + } + FlxG.fixedTimestep = false; + moveCameraSection(); + + //omg its that ms text from earlier + msTxt = new FlxText(0, 0, 0, ""); + msTxt.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); + msTxt.scrollFactor.set(); + msTxt.setFormat("vcr.ttf", 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + if (ClientPrefs.hudType == 'Tails Gets Trolled V4') msTxt.setFormat("calibri.ttf", 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + if (ClientPrefs.hudType == 'Dave and Bambi') msTxt.setFormat("comic.ttf", 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + if (ClientPrefs.hudType == 'Doki Doki+') msTxt.setFormat("Aller_rg.ttf", 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + msTxt.x = 408 + 250; + msTxt.y = 290 - 25; + if (PlayState.isPixelStage) { + msTxt.x = 408 + 260; + msTxt.y = 290 + 20; + } + msTxt.x += ClientPrefs.comboOffset[0]; + msTxt.y -= ClientPrefs.comboOffset[1]; + msTxt.active = false; + msTxt.visible = false; + insert(members.indexOf(strumLineNotes), msTxt); + if (ClientPrefs.hudType == 'Dave and Bambi') + { + if (ClientPrefs.longHPBar) + { + healthBarBG = new AttachedSprite('longDnBHealthBar'); + } else + { + healthBarBG = new AttachedSprite('DnBHealthBar'); + } + healthBarBG.y = FlxG.height * 0.89; + if(ClientPrefs.downScroll) healthBarBG.y = 0.11 * FlxG.height; + healthBarBG.screenCenter(X); + healthBarBG.scrollFactor.set(); + healthBarBG.xAdd = -4; + healthBarBG.yAdd = -4; + healthBarBG.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + add(healthBarBG); + + healthBar = new FlxBar(healthBarBG.x + 4, healthBarBG.y + 4, (opponentChart ? LEFT_TO_RIGHT : RIGHT_TO_LEFT), Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, + 'displayedHealth', 0, maxHealth); + healthBar.scrollFactor.set(); + // healthBar + healthBar.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + healthBar.alpha = ClientPrefs.healthBarAlpha; + healthBarBG.sprTracker = healthBar; + insert(members.indexOf(healthBarBG), healthBar); + } + if (ClientPrefs.hudType == 'Doki Doki+') + { + if (ClientPrefs.longHPBar) + { + healthBarBG = new AttachedSprite('longDokiHealthBar'); + } else + { + healthBarBG = new AttachedSprite('dokiHealthBar'); + } + healthBarBG.y = FlxG.height * 0.89; + healthBarBG.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + if(ClientPrefs.downScroll) healthBarBG.y = 0.11 * FlxG.height; + healthBarBG.screenCenter(X); + healthBarBG.scrollFactor.set(); + healthBarBG.xAdd = -4; + healthBarBG.yAdd = -4; + add(healthBarBG); + + healthBar = new FlxBar(healthBarBG.x + 4, healthBarBG.y + 4, (opponentChart ? LEFT_TO_RIGHT : RIGHT_TO_LEFT), Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, + 'displayedHealth', 0, maxHealth); + healthBar.scrollFactor.set(); + // healthBar + healthBar.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + healthBar.alpha = ClientPrefs.healthBarAlpha; + healthBarBG.sprTracker = healthBar; + add(healthBar); + } else if (ClientPrefs.hudType != 'Dave and Bambi' && ClientPrefs.hudType != 'Doki Doki+') { + if (ClientPrefs.longHPBar) + { + healthBarBG = new AttachedSprite('longHealthBar'); + } else + { + healthBarBG = new AttachedSprite('healthBar'); + } + healthBarBG.y = FlxG.height * 0.89; + healthBarBG.screenCenter(X); + healthBarBG.scrollFactor.set(); + healthBarBG.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + healthBarBG.xAdd = -4; + healthBarBG.yAdd = -4; + add(healthBarBG); + if(ClientPrefs.downScroll) healthBarBG.y = 0.11 * FlxG.height; + + healthBar = new FlxBar(healthBarBG.x + 4, healthBarBG.y + 4, (opponentChart ? LEFT_TO_RIGHT : RIGHT_TO_LEFT), Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, + 'displayedHealth', 0, maxHealth); + healthBar.scrollFactor.set(); + // healthBar + healthBar.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + healthBar.alpha = ClientPrefs.healthBarAlpha; + add(healthBar); + healthBarBG.sprTracker = healthBar; + } + + iconP1 = new HealthIcon(boyfriend.healthIcon, true); + iconP1.y = healthBar.y - 75; + iconP1.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + iconP1.alpha = ClientPrefs.healthBarAlpha; + add(iconP1); + + iconP2 = new HealthIcon(dad.healthIcon, false); + iconP2.y = healthBar.y - 75; + iconP2.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + iconP2.alpha = ClientPrefs.healthBarAlpha; + add(iconP2); + reloadHealthBarColors(); + + if (ClientPrefs.bfIconStyle == 'VS Nonsense V2') iconP1.changeIcon('bfnonsense'); + if (ClientPrefs.bfIconStyle == 'Doki Doki+') iconP1.changeIcon('bfdoki'); + if (ClientPrefs.bfIconStyle == 'Leather Engine') iconP1.changeIcon('bfleather'); + + if (ClientPrefs.timeBarType == 'Disabled') { + timeBarBG.destroy(); + timeBar.destroy(); + } + + if (ClientPrefs.hudType == 'Kade Engine') { + // Add Engine watermark + EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); + EngineWatermark.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + EngineWatermark.scrollFactor.set(); + add(EngineWatermark); + EngineWatermark.text = SONG.song + " " + CoolUtil.difficultyString() + " | JSE " + MainMenuState.psychEngineJSVersion; + } + if (ClientPrefs.hudType == 'JS Engine') { + // Add Engine watermark + EngineWatermark = new FlxText(4,FlxG.height * 0.1 - 70,0,"", 15); + EngineWatermark.setFormat(Paths.font("vcr.ttf"), 18, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + EngineWatermark.scrollFactor.set(); + if (ClientPrefs.downScroll) EngineWatermark.y = (FlxG.height * 0.9 + 50); + add(EngineWatermark); + EngineWatermark.text = "You are now playing " + SONG.song + " on " + CoolUtil.difficultyString() + "! (JSE v" + MainMenuState.psychEngineJSVersion + ")"; + } + if (ClientPrefs.hudType == 'Dave and Bambi') { + // Add Engine watermark + EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); + EngineWatermark.setFormat(Paths.font("comic.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + EngineWatermark.scrollFactor.set(); + add(EngineWatermark); + EngineWatermark.text = SONG.song; + } + if (ClientPrefs.hudType == 'Doki Doki+') { + // Add Engine watermark + EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); + add(EngineWatermark); + } + if (ClientPrefs.hudType == 'Leather Engine') { + // Add Engine watermark BECAUSE THE ENGINE THING IS dumb + EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); + add(EngineWatermark); + } + if (ClientPrefs.hudType == 'VS Impostor') { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference + // Add Engine watermark + EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); + add(EngineWatermark); + } + if (ClientPrefs.hudType == 'Psych Engine') { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference + // Add Engine watermark + EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); + add(EngineWatermark); + } + if (ClientPrefs.hudType == 'Tails Gets Trolled V4') { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference + // Add Engine watermark + EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); + add(EngineWatermark); + } + if (ClientPrefs.hudType == "Mic'd Up") { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference + // Add Engine watermark + EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); + add(EngineWatermark); + } + if (ClientPrefs.hudType == 'Box Funkin') { //unfortunately i have to do this because otherwise enginewatermark calls a null object reference + // Add Engine watermark + EngineWatermark = new FlxText(4,FlxG.height * 0.9 + 50,0,"", 16); + add(EngineWatermark); + } + + if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) { + //hitTxt = new FlxText(STRUM_X + (FlxG.width / 2) - 248, 20, 10000, "", 42); + hitTxt = new FlxText(0, 20, 10000, "test", 42); + hitTxt.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + hitTxt.scrollFactor.set(); + hitTxt.borderSize = 2; + hitTxt.visible = true; + hitTxt.cameras = [camHUD]; + //hitTxt.alignment = FlxTextAlign.LEFT; // center the text + //hitTxt.screenCenter(X); + hitTxt.screenCenter(Y); + add(hitTxt); + var chromaScreen = new FlxSprite(-5000, -2000).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.GREEN); + chromaScreen.scrollFactor.set(0, 0); + chromaScreen.scale.set(3, 3); + chromaScreen.updateHitbox(); + add(chromaScreen); + } + + if (ClientPrefs.hudType == 'Kade Engine') + { + scoreTxt = new FlxText(0, healthBarBG.y + 50, FlxG.width, "", 20); + scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + scoreTxt.borderSize = 1; + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + add(scoreTxt); + } + if (ClientPrefs.hudType == 'JS Engine') + { + scoreTxt = new FlxText(0, healthBarBG.y + 50, FlxG.width, "", 20); + scoreTxt.setFormat(Paths.font("vcr.ttf"), 18, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + scoreTxt.borderSize = 2; + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + add(scoreTxt); + } + if (ClientPrefs.hudType == "Mic'd Up") + { + scoreTxt = new FlxText(healthBarBG.x - (healthBarBG.width / 2), healthBarBG.y - 26, 0, "", 20); + if (ClientPrefs.downScroll) + scoreTxt.y = healthBarBG.y + 18; + scoreTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, RIGHT); + scoreTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + scoreTxt.scrollFactor.set(); + add(scoreTxt); + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + + missTxt = new FlxText(scoreTxt.x, scoreTxt.y - 26, 0, "", 20); + if (ClientPrefs.downScroll) + missTxt.y = scoreTxt.y + 26; + missTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, RIGHT); + missTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + missTxt.scrollFactor.set(); + add(missTxt); + missTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + + accuracyTxt = new FlxText(missTxt.x, missTxt.y - 26, 0, "", 20); + if (ClientPrefs.downScroll) + accuracyTxt.y = missTxt.y + 26; + accuracyTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, RIGHT); + accuracyTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + accuracyTxt.scrollFactor.set(); + add(accuracyTxt); + accuracyTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + + comboTxt = new FlxText(scoreTxt.x, scoreTxt.y + 26, 0, "", 21); + if (ClientPrefs.downScroll) + comboTxt.y = scoreTxt.y - 26; + comboTxt.setFormat(Paths.font("vcr.ttf"), 21, FlxColor.WHITE, RIGHT); + comboTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + comboTxt.scrollFactor.set(); + add(comboTxt); + comboTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + + npsTxt = new FlxText(accuracyTxt.x, accuracyTxt.y - 46, 0, "", 20); + if (ClientPrefs.downScroll) + npsTxt.y = accuracyTxt.y + 46; + npsTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, RIGHT); + npsTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + npsTxt.scrollFactor.set(); + add(npsTxt); + npsTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + } + if (ClientPrefs.hudType == 'Box Funkin') + { + scoreTxt = new FlxText(25, healthBarBG.y - 26, 0, "", 21); + if (ClientPrefs.downScroll) + scoreTxt.y = healthBarBG.y + 26; + scoreTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); + scoreTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + scoreTxt.scrollFactor.set(); + add(scoreTxt); + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + + missTxt = new FlxText(scoreTxt.x, scoreTxt.y - 26, 0, "", 21); + if (ClientPrefs.downScroll) + missTxt.y = scoreTxt.y + 26; + missTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); + missTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + missTxt.scrollFactor.set(); + add(missTxt); + missTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + + accuracyTxt = new FlxText(missTxt.x, missTxt.y - 26, 0, "", 21); + if (ClientPrefs.downScroll) + accuracyTxt.y = missTxt.y + 26; + accuracyTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); + accuracyTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + accuracyTxt.scrollFactor.set(); + add(accuracyTxt); + accuracyTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + + comboTxt = new FlxText(scoreTxt.x, scoreTxt.y + 26, 0, "", 21); + if (ClientPrefs.downScroll) + comboTxt.y = scoreTxt.y - 26; + comboTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); + comboTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + comboTxt.scrollFactor.set(); + add(comboTxt); + comboTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + + npsTxt = new FlxText(accuracyTxt.x, accuracyTxt.y - 46, 0, "", 21); + if (ClientPrefs.downScroll) + npsTxt.y = accuracyTxt.y + 46; + npsTxt.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, RIGHT); + npsTxt.setBorderStyle(OUTLINE, 0xFF000000, 3, 1); + npsTxt.scrollFactor.set(); + add(npsTxt); + npsTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + } + if (ClientPrefs.hudType == 'Leather Engine') + { + scoreTxt = new FlxText(0, healthBarBG.y + 50, FlxG.width, "", 20); + scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + scoreTxt.borderSize = 1; + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + add(scoreTxt); + } + if (ClientPrefs.hudType == 'Dave and Bambi') + { + scoreTxt = new FlxText(0, healthBarBG.y + 40, FlxG.width, "", 20); + scoreTxt.setFormat(Paths.font("comic.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + scoreTxt.borderSize = 1.25; + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + add(scoreTxt); + } + if (ClientPrefs.hudType == 'Psych Engine') + { + scoreTxt = new FlxText(0, healthBarBG.y + 36, FlxG.width, "", 20); + scoreTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + scoreTxt.borderSize = 1.25; + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + add(scoreTxt); + } + if (ClientPrefs.hudType == 'Doki Doki+') + { + scoreTxt = new FlxText(0, healthBarBG.y + 48, FlxG.width, "", 20); + scoreTxt.setFormat(Paths.font("Aller_rg.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + scoreTxt.borderSize = 1.25; + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + add(scoreTxt); + } + if (ClientPrefs.hudType == 'Tails Gets Trolled V4') + { + scoreTxt = new FlxText(0, healthBarBG.y + 48, FlxG.width, "", 20); + scoreTxt.setFormat(Paths.font("calibri.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + scoreTxt.borderSize = 1.25; + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + add(scoreTxt); + } + if (ClientPrefs.hudType == 'VS Impostor') + { + scoreTxt = new FlxText(0, healthBarBG.y + 36, FlxG.width, "", 20); + scoreTxt.scrollFactor.set(); + scoreTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + scoreTxt.borderSize = 1.25; + scoreTxt.visible = !ClientPrefs.hideHud || !ClientPrefs.showcaseMode; + add(scoreTxt); + } + if (ClientPrefs.hideScore || ClientPrefs.showcaseMode) { + scoreTxt.destroy(); + healthBarBG.visible = false; + healthBar.visible = false; + iconP2.visible = iconP1.visible = false; + } + if (!ClientPrefs.charsAndBG) { + remove(dadGroup); + remove(boyfriendGroup); + remove(gfGroup); + gfGroup.destroy(); + dadGroup.destroy(); + boyfriendGroup.destroy(); + } + if (ClientPrefs.scoreTxtSize > 0 && scoreTxt != null) scoreTxt.size = ClientPrefs.scoreTxtSize; + if (!ClientPrefs.hideScore) updateScore(); + + judgementCounter = new FlxText(0, FlxG.height / 2 - (ClientPrefs.hudType != 'Box Funkin' || ClientPrefs.hudType != "Mic'd Up" ? 80 : 350), 0, "", 20); + judgementCounter.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + if (ClientPrefs.hudType == 'Box Funkin') judgementCounter.setFormat(Paths.font("MilkyNice.ttf"), 21, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + judgementCounter.borderSize = 2; + judgementCounter.scrollFactor.set(); + judgementCounter.visible = ClientPrefs.ratingCounter && !ClientPrefs.showcaseMode; + if (!ClientPrefs.noMarvJudge) + { + judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nMarvelous!!!: ' + marvs + '\nSicks!!: ' + sicks + '\nGoods!: ' + goods + '\nBads: ' + bads + '\nShits: ' + shits + '\nMisses: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + + if (ClientPrefs.hudType == 'Doki Doki+') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nVery Doki: ' + marvs + '\nDoki: ' + sicks + '\nGood: ' + goods + '\nOK: ' + bads + '\nNO: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + + if (ClientPrefs.hudType == 'VS Impostor') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSO SUSSY: ' + marvs + '\nSussy: ' + sicks + '\nSus: ' + goods + '\nSad: ' + bads + '\nAss: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + } + if (ClientPrefs.noMarvJudge) + { + judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSicks!!: ' + sicks + '\nGoods!: ' + goods + '\nBads: ' + bads + '\nShits: ' + shits + '\nMisses: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + + if (ClientPrefs.hudType == 'Doki Doki+') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nDoki: ' + sicks + '\nGood: ' + goods + '\nOK: ' + bads + '\nNO: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + + if (ClientPrefs.hudType == 'VS Impostor') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSussy: ' + sicks + '\nSus: ' + goods + '\nSad: ' + bads + '\nAss: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + } + judgementCounter.text += (ClientPrefs.showNPS ? '\nNPS (Max): ' + FlxStringUtil.formatMoney(nps, false) + ' (' + FlxStringUtil.formatMoney(maxNPS, false) + ')' : ''); + if (ClientPrefs.opponentRateCount) judgementCounter.text += '\n\nOpponent Hits: ' + FlxStringUtil.formatMoney(enemyHits, false) + ' / ' + FlxStringUtil.formatMoney(opponentNoteTotal, false) + ' (' + FlxMath.roundDecimal((enemyHits / opponentNoteTotal) * 100, 2) + '%)' + (ClientPrefs.showNPS ? '\nOpponent NPS (Max): ' + FlxStringUtil.formatMoney(oppNPS, false) + ' (' + FlxStringUtil.formatMoney(maxOppNPS, false) + ')' : ''); + add(judgementCounter); + + pauseWarnText = new FlxText(400, FlxG.height / 2 - 20, 0, "Pausing is disabled! Turn it back on in Settings -> Gameplay -> 'Force Disable Pausing'", 16); + pauseWarnText.cameras = [camHUD]; + pauseWarnText.scrollFactor.set(); + pauseWarnText.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + pauseWarnText.borderSize = 1.25; + pauseWarnText.x += 20; + pauseWarnText.y -= 25; + pauseWarnText.alpha = 0; + + if (cpuControlled && !ClientPrefs.showcaseMode) + { + if (ClientPrefs.hudType == 'Psych Engine') + { + botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); + botplayTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + botplayTxt.scrollFactor.set(); + botplayTxt.borderSize = 1.25; + botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; + add(botplayTxt); + if (ClientPrefs.downScroll) + botplayTxt.y = timeBarBG.y - 78; + } + if (ClientPrefs.hudType == 'JS Engine') + { + botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "Botplay Mode", 30); + botplayTxt.setFormat(Paths.font("vcr.ttf"), 30, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + botplayTxt.scrollFactor.set(); + botplayTxt.borderSize = 1.5; + botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; + add(botplayTxt); + if (ClientPrefs.downScroll) + botplayTxt.y = timeBarBG.y - 78; + } + if (ClientPrefs.hudType == 'Box Funkin') + { + botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); + botplayTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + botplayTxt.scrollFactor.set(); + botplayTxt.borderSize = 1.25; + botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; + add(botplayTxt); + if (ClientPrefs.downScroll) + botplayTxt.y = timeBarBG.y - 78; + } + if (ClientPrefs.hudType == "Mic'd Up") + { + botplayTxt = new FlxText((healthBarBG.width / 2), healthBar.y, 0, "AutoPlayCPU", 20); + botplayTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + botplayTxt.scrollFactor.set(); + botplayTxt.screenCenter(X); + botplayTxt.borderSize = 3; + botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; + add(botplayTxt); + if (ClientPrefs.downScroll) + botplayTxt.y = timeBarBG.y - 78; + } + if (ClientPrefs.hudType == 'Leather Engine') + { + botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "", 32); //yeah leather engine has no botplay text soooo + add(botplayTxt); + if (ClientPrefs.downScroll) + botplayTxt.y = timeBarBG.y - 78; + botplayTxt.visible = false; + } + if (ClientPrefs.hudType == 'Kade Engine') + { + botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); + botplayTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + botplayTxt.scrollFactor.set(); + botplayTxt.borderSize = 1.25; + botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; + add(botplayTxt); + if (ClientPrefs.downScroll) + botplayTxt.y = timeBarBG.y - 78; + } + if (ClientPrefs.hudType == 'Doki Doki+') + { + botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); + botplayTxt.setFormat(Paths.font("Aller_rg.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + botplayTxt.scrollFactor.set(); + botplayTxt.borderSize = 1.25; + botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; + add(botplayTxt); + if (ClientPrefs.downScroll) + botplayTxt.y = timeBarBG.y - 78; + } + if (ClientPrefs.hudType == 'Tails Gets Trolled V4') + { + botplayTxt = new FlxText(400, timeBarBG.y + (ClientPrefs.downScroll ? -78 : 55), FlxG.width - 800, "[BUTTPLUG]", 32); + botplayTxt.setFormat(Paths.font("calibri.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + botplayTxt.scrollFactor.set(); + botplayTxt.borderSize = 1.25; + botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; + add(botplayTxt); + if (ClientPrefs.downScroll) + botplayTxt.y = timeBarBG.y - 78; + } + if (ClientPrefs.hudType == 'Dave and Bambi') + { + botplayTxt = new FlxText(400, timeBarBG.y + 55, FlxG.width - 800, "BOTPLAY", 32); + botplayTxt.setFormat(Paths.font("comic.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + botplayTxt.scrollFactor.set(); + botplayTxt.borderSize = 1.25; + botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; + add(botplayTxt); + if (ClientPrefs.downScroll) + botplayTxt.y = timeBarBG.y - 78; + } + if (ClientPrefs.hudType == 'VS Impostor') + { + botplayTxt = new FlxText(400, healthBarBG.y - 55, FlxG.width - 800, "BOTPLAY", 32); + botplayTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + botplayTxt.scrollFactor.set(); + botplayTxt.borderSize = 1.25; + botplayTxt.visible = cpuControlled && !ClientPrefs.showcaseMode; + add(botplayTxt); + if (ClientPrefs.downScroll) + { + botplayTxt.y = timeBarBG.y - 78; + } + } + } + if (ClientPrefs.communityGameBot || ClientPrefs.showcaseMode && botplayTxt != null) botplayTxt.destroy(); + + laneunderlayOpponent.cameras = [camHUD]; + laneunderlay.cameras = [camHUD]; + strumLineNotes.cameras = [camHUD]; + grpNoteSplashes.cameras = [camHUD]; + notes.cameras = [camHUD]; + healthBar.cameras = [camHUD]; + healthBarBG.cameras = [camHUD]; + iconP1.cameras = [camHUD]; + iconP2.cameras = [camHUD]; + EngineWatermark.cameras = [camHUD]; + judgementCounter.cameras = [camHUD]; + scoreTxt.cameras = [camHUD]; + if(ClientPrefs.hudType == "Mic'd Up" || ClientPrefs.hudType == 'Box Funkin') + { + missTxt.cameras = [camHUD]; + accuracyTxt.cameras = [camHUD]; + npsTxt.cameras = [camHUD]; + comboTxt.cameras = [camHUD]; + } + if (botplayTxt != null) botplayTxt.cameras = [camHUD]; + timeBar.cameras = [camHUD]; + timeBarBG.cameras = [camHUD]; + timeTxt.cameras = [camHUD]; + timePercentTxt.cameras = [camHUD]; + doof.cameras = [camHUD]; + + #if android + addAndroidControls(); + androidControls.visible = false; + #end + + // if (SONG.song == 'South') + // FlxG.camera.alpha = 0.7; + // UI_camera.zoom = 1; + + // cameras = [FlxG.cameras.list[1]]; + startingSong = true; + // WINDOW TITLE POG + MusicBeatState.windowNameSuffix = " - " + SONG.song + " " + (isStoryMode ? "(Story Mode)" : "(Freeplay)"); + + #if LUA_ALLOWED + for (notetype in noteTypeMap.keys()) + { + startLuasOnFolder(SUtil.getPath() + 'custom_notetypes/' + notetype + '.lua'); + } + for (event in eventPushedMap.keys()) + { + startLuasOnFolder(SUtil.getPath() + 'custom_events/' + event + '.lua'); + } + #end + noteTypeMap.clear(); + noteTypeMap = null; + eventPushedMap.clear(); + eventPushedMap = null; + + if(eventNotes.length > 1) + { + for (event in eventNotes) event.strumTime -= eventNoteEarlyTrigger(event); + eventNotes.sort(sortByTime); + } + + // SONG SPECIFIC SCRIPTS + #if LUA_ALLOWED + var filesPushed:Array = []; + var foldersToCheck:Array = [SUtil.getPath() + Paths.getPreloadPath('data/' + Paths.formatToSongPath(SONG.song) + '/')]; + + #if MODS_ALLOWED + foldersToCheck.insert(0, Paths.mods('data/' + Paths.formatToSongPath(SONG.song) + '/')); + if(Paths.currentModDirectory != null && Paths.currentModDirectory.length > 0) + foldersToCheck.insert(0, Paths.mods(Paths.currentModDirectory + '/data/' + Paths.formatToSongPath(SONG.song) + '/')); + + for(mod in Paths.getGlobalMods()) + foldersToCheck.insert(0, Paths.mods(mod + '/data/' + Paths.formatToSongPath(SONG.song) + '/' ));// using push instead of insert because these should run after everything else + #end + + for (folder in foldersToCheck) + { + if(FileSystem.exists(folder)) + { + for (file in FileSystem.readDirectory(folder)) + { + if(file.endsWith('.lua') && !filesPushed.contains(file)) + { + luaArray.push(new FunkinLua(folder + file)); + filesPushed.push(file); + } + } + } + } + #end + + var daSong:String = Paths.formatToSongPath(curSong); + if (isStoryMode && !seenCutscene) + { + switch (daSong) + { + case "monster": + var whiteScreen:FlxSprite = new FlxSprite(0, 0).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.WHITE); + add(whiteScreen); + whiteScreen.scrollFactor.set(); + whiteScreen.blend = ADD; + camHUD.visible = false; + snapCamFollowToPos(dad.getMidpoint().x + 150, dad.getMidpoint().y - 100); + inCutscene = true; + + FlxTween.tween(whiteScreen, {alpha: 0}, 1, { + startDelay: 0.1, + ease: FlxEase.linear, + onComplete: function(twn:FlxTween) + { + camHUD.visible = true; + remove(whiteScreen); + startCountdown(); + } + }); + FlxG.sound.play(Paths.soundRandom('thunder_', 1, 2)); + if(gf != null) gf.playAnim('scared', true); + boyfriend.playAnim('scared', true); + + case "winter-horrorland": + var blackScreen:FlxSprite = new FlxSprite().makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK); + add(blackScreen); + blackScreen.scrollFactor.set(); + camHUD.visible = false; + inCutscene = true; + + FlxTween.tween(blackScreen, {alpha: 0}, 0.7, { + ease: FlxEase.linear, + onComplete: function(twn:FlxTween) { + remove(blackScreen); + } + }); + FlxG.sound.play(Paths.sound('Lights_Turn_On')); + snapCamFollowToPos(400, -2050); + FlxG.camera.focusOn(camFollow); + 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' | 'roses' | 'thorns': + if(daSong == 'roses') FlxG.sound.play(Paths.sound('ANGRY')); + schoolIntro(doof); + + case 'ugh' | 'guns' | 'stress': + tankIntro(); + + default: + startCountdown(); + } + seenCutscene = true; + } + else + { + startCountdown(); + } + RecalculateRating(); + + //PRECACHING MISS SOUNDS BECAUSE I THINK THEY CAN LAG PEOPLE AND FUCK THEM UP IDK HOW HAXE WORKS + if (hitSoundString != "none") + hitsound = FlxG.sound.load(Paths.sound("hitsounds/" + Std.string(hitSoundString).toLowerCase())); + if (hitSoundString == 'Randomized') + { + hitsound = FlxG.sound.load(Paths.sound("hitsounds/" + 'osu!mania')); + hitsound2 = FlxG.sound.load(Paths.sound("hitsounds/" + 'dave and bambi')); + hitsound3 = FlxG.sound.load(Paths.sound("hitsounds/" + 'indie cross')); + hitsound4 = FlxG.sound.load(Paths.sound("hitsounds/" + 'snap')); + hitsound5 = FlxG.sound.load(Paths.sound("hitsounds/" + 'clap')); + hitsound6 = FlxG.sound.load(Paths.sound("hitsounds/" + 'generic click')); + hitsound7 = FlxG.sound.load(Paths.sound("hitsounds/" + 'keyboard click')); + hitsound8 = FlxG.sound.load(Paths.sound("hitsounds/" + 'vine boom')); + hitsound9 = FlxG.sound.load(Paths.sound("hitsounds/" + 'adofai')); + hitsound10 = FlxG.sound.load(Paths.sound("hitsounds/" + 'discord ping')); + hitsound11 = FlxG.sound.load(Paths.sound("hitsounds/" + "i'm spongebob!")); + } + if(ClientPrefs.hitsoundVolume > 0) precacheList.set('hitsound', 'sound'); + if(ClientPrefs.hitsoundVolume > 0 && hitSoundString == 'Randomized') + { + precacheList.set('hitsound', 'sound'); + precacheList.set('hitsound2', 'sound'); + precacheList.set('hitsound3', 'sound'); + precacheList.set('hitsound4', 'sound'); + precacheList.set('hitsound5', 'sound'); + precacheList.set('hitsound6', 'sound'); + precacheList.set('hitsound7', 'sound'); + precacheList.set('hitsound8', 'sound'); + precacheList.set('hitsound9', 'sound'); + precacheList.set('hitsound10', 'sound'); + precacheList.set('hitsound11', 'sound'); + hitsound.volume = ClientPrefs.hitsoundVolume; + hitsound.pitch = playbackRate; + hitsound2.volume = ClientPrefs.hitsoundVolume; + hitsound2.pitch = playbackRate; + hitsound3.volume = ClientPrefs.hitsoundVolume; + hitsound3.pitch = playbackRate; + hitsound4.volume = ClientPrefs.hitsoundVolume; + hitsound4.pitch = playbackRate; + hitsound5.volume = ClientPrefs.hitsoundVolume; + hitsound5.pitch = playbackRate; + hitsound6.volume = ClientPrefs.hitsoundVolume; + hitsound6.pitch = playbackRate; + hitsound7.volume = ClientPrefs.hitsoundVolume; + hitsound7.pitch = playbackRate; + hitsound8.volume = ClientPrefs.hitsoundVolume; + hitsound8.pitch = playbackRate; + hitsound9.volume = ClientPrefs.hitsoundVolume; + hitsound9.pitch = playbackRate; + hitsound10.volume = ClientPrefs.hitsoundVolume; + hitsound10.pitch = playbackRate; + hitsound11.volume = ClientPrefs.hitsoundVolume; + hitsound11.pitch = playbackRate; + } + hitsound.volume = ClientPrefs.hitsoundVolume; + hitsound.pitch = playbackRate; + precacheList.set('missnote1', 'sound'); + precacheList.set('missnote2', 'sound'); + precacheList.set('missnote3', 'sound'); + + if (PauseSubState.songName != null) { + precacheList.set(PauseSubState.songName, 'music'); + } else if(ClientPrefs.pauseMusic != 'None') { + precacheList.set(Paths.formatToSongPath(ClientPrefs.pauseMusic), 'music'); + } + + precacheList.set('alphabet', 'image'); + + #if desktop + // Updating Discord Rich Presence. + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); + #end + + + if(!ClientPrefs.controllerMode) + { + FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress); + FlxG.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyRelease); + } + callOnLuas('onCreatePost', []); + + super.create(); + + if(cpuControlled && ClientPrefs.randomBotplayText && ClientPrefs.hudType != 'Leather Engine' && botplayTxt != null) + { + botplayTxt.text = theListBotplay[FlxG.random.int(0, theListBotplay.length - 1)]; + } + + cacheCountdown(); + if (ClientPrefs.ratesAndCombo) cachePopUpScore(); //Caching the ratings is unnecessary if you turn off rating popups + for (key => type in precacheList) + { + //trace('Key $key is type $type'); + switch(type) + { + case 'image': + Paths.image(key); + case 'sound': + Paths.sound(key); + case 'music': + Paths.music(key); + } + } + if (!ClientPrefs.memLeaks) + { + Paths.clearUnusedMemory(); + } + + CustomFadeTransition.nextCamera = camOther; + if(eventNotes.length < 1) checkEventNote(); + } + + #if (!flash && sys) + public var runtimeShaders:Map> = new Map>(); + public function createRuntimeShader(name:String):FlxRuntimeShader + { + if(!ClientPrefs.shaders) return new FlxRuntimeShader(); + + #if (!flash && MODS_ALLOWED && sys) + if(!runtimeShaders.exists(name) && !initLuaShader(name)) + { + FlxG.log.warn('Shader $name is missing!'); + return new FlxRuntimeShader(); + } + + var arr:Array = runtimeShaders.get(name); + return new FlxRuntimeShader(arr[0], arr[1]); + #else + FlxG.log.warn("Platform unsupported for Runtime Shaders!"); + return null; + #end + } + + #if !android + public function initLuaShader(name:String, ?glslVersion:Int = 120) + #else + public function initLuaShader(name:String, ?glslVersion:Int = 100) + #end + { + if(!ClientPrefs.shaders) return false; + + if(runtimeShaders.exists(name)) + { + FlxG.log.warn('Shader $name was already initialized!'); + return true; + } + + var foldersToCheck:Array = [Paths.mods('shaders/')]; + if(Paths.currentModDirectory != null && Paths.currentModDirectory.length > 0) + foldersToCheck.insert(0, Paths.mods(Paths.currentModDirectory + '/shaders/')); + + for(mod in Paths.getGlobalMods()) + foldersToCheck.insert(0, Paths.mods(mod + '/shaders/')); + + for (folder in foldersToCheck) + { + if(FileSystem.exists(folder)) + { + var frag:String = folder + name + '.frag'; + var vert:String = folder + name + '.vert'; + var found:Bool = false; + if(FileSystem.exists(frag)) + { + frag = File.getContent(frag); + found = true; + } + else frag = null; + + if (FileSystem.exists(vert)) + { + vert = File.getContent(vert); + found = true; + } + else vert = null; + + if(found) + { + runtimeShaders.set(name, [frag, vert]); + //trace('Found shader $name!'); + return true; + } + } + } + FlxG.log.warn('Missing shader $name .frag AND .vert files!'); + return false; + } + #end + + function set_songSpeed(value:Float):Float + { + if(generatedMusic) + { + var ratio:Float = value / songSpeed; //funny word huh + if (ratio != 1) + { + for (note in notes){ + if (note == null) + continue; + note.resizeByRatio(ratio); + } + for (note in unspawnNotes){ + if (note == null) + continue; + note.resizeByRatio(ratio); + } + } + } + songSpeed = value; + noteKillOffset = 350 / songSpeed; + return value; + } + + function set_playbackRate(value:Float):Float + { + if(generatedMusic) + { + if(vocals != null) vocals.pitch = value; + FlxG.sound.music.pitch = value; + } + playbackRate = value; + FlxAnimationController.globalSpeed = value; + trace('Anim speed: ' + FlxAnimationController.globalSpeed); + Conductor.safeZoneOffset = (ClientPrefs.safeFrames / 60) * 1000 * value; + setOnLuas('playbackRate', playbackRate); + return value; + } + + public function addTextToDebug(text:String, color:FlxColor) { + #if LUA_ALLOWED + luaDebugGroup.forEachAlive(function(spr:DebugLuaText) { + spr.y += 20; + }); + + if(luaDebugGroup.members.length > 34) { + var blah = luaDebugGroup.members[34]; + blah.destroy(); + luaDebugGroup.remove(blah); + } + luaDebugGroup.insert(0, new DebugLuaText(text, luaDebugGroup, color)); + #end + } + + public function reloadHealthBarColors() { + if (!opponentChart) healthBar.createFilledBar(FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]), + FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2])); + else healthBar.createFilledBar(FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2]), + FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])); + + healthBar.updateBar(); + } + + public function addCharacterToList(newCharacter:String, type:Int) { + switch(type) { + case 0: + if(!boyfriendMap.exists(newCharacter)) { + var newBoyfriend:Boyfriend = new Boyfriend(0, 0, newCharacter); + boyfriendMap.set(newCharacter, newBoyfriend); + boyfriendGroup.add(newBoyfriend); + startCharacterPos(newBoyfriend); + newBoyfriend.alpha = 0.00001; + startCharacterLua(newBoyfriend.curCharacter); + } + + case 1: + if(!dadMap.exists(newCharacter)) { + var newDad:Character = new Character(0, 0, newCharacter); + dadMap.set(newCharacter, newDad); + dadGroup.add(newDad); + startCharacterPos(newDad, true); + newDad.alpha = 0.00001; + startCharacterLua(newDad.curCharacter); + } + + case 2: + if(gf != null && !gfMap.exists(newCharacter)) { + var newGf:Character = new Character(0, 0, newCharacter); + newGf.scrollFactor.set(0.95, 0.95); + gfMap.set(newCharacter, newGf); + gfGroup.add(newGf); + startCharacterPos(newGf); + newGf.alpha = 0.00001; + startCharacterLua(newGf.curCharacter); + } + } + } + + function startCharacterLua(name:String) + { + #if LUA_ALLOWED + var doPush:Bool = false; + var luaFile:String = 'characters/' + name + '.lua'; + #if MODS_ALLOWED + if(FileSystem.exists(Paths.modFolders(luaFile))) { + luaFile = Paths.modFolders(luaFile); + doPush = true; + } else { + luaFile = SUtil.getPath() + Paths.getPreloadPath(luaFile); + if(FileSystem.exists(luaFile)) { + doPush = true; + } + } + #else + luaFile = Paths.getPreloadPath(luaFile); + if(Assets.exists(luaFile)) { + doPush = true; + } + #end + + if(doPush) + { + for (script in luaArray) + { + if(script.scriptName == luaFile) return; + } + luaArray.push(new FunkinLua(luaFile)); + } + #end + } + + public function addShaderToCamera(cam:String,effect:Dynamic){//STOLE FROM ANDROMEDA // actually i got it from old psych engine + + + + switch(cam.toLowerCase()) { + case 'camhud' | 'hud': + camHUDShaders.push(effect); + var newCamEffects:Array=[]; // IT SHUTS HAXE UP IDK WHY BUT WHATEVER IDK WHY I CANT JUST ARRAY + for(i in camHUDShaders){ + newCamEffects.push(new ShaderFilter(i.shader)); + } + camHUD.setFilters(newCamEffects); + case 'camother' | 'other': + camOtherShaders.push(effect); + var newCamEffects:Array=[]; // IT SHUTS HAXE UP IDK WHY BUT WHATEVER IDK WHY I CANT JUST ARRAY + for(i in camOtherShaders){ + newCamEffects.push(new ShaderFilter(i.shader)); + } + camOther.setFilters(newCamEffects); + case 'camgame' | 'game': + camGameShaders.push(effect); + var newCamEffects:Array=[]; // IT SHUTS HAXE UP IDK WHY BUT WHATEVER IDK WHY I CANT JUST ARRAY + for(i in camGameShaders){ + newCamEffects.push(new ShaderFilter(i.shader)); + } + camGame.setFilters(newCamEffects); + default: + if(modchartSprites.exists(cam)) { + Reflect.setProperty(modchartSprites.get(cam),"shader",effect.shader); + } else if(modchartTexts.exists(cam)) { + Reflect.setProperty(modchartTexts.get(cam),"shader",effect.shader); + } else { + var OBJ = Reflect.getProperty(PlayState.instance,cam); + Reflect.setProperty(OBJ,"shader", effect.shader); + } + + + + + } + + + + + } + + public function removeShaderFromCamera(cam:String,effect:ShaderEffect){ + + + switch(cam.toLowerCase()) { + case 'camhud' | 'hud': + camHUDShaders.remove(effect); + var newCamEffects:Array=[]; + for(i in camHUDShaders){ + newCamEffects.push(new ShaderFilter(i.shader)); + } + camHUD.setFilters(newCamEffects); + case 'camother' | 'other': + camOtherShaders.remove(effect); + var newCamEffects:Array=[]; + for(i in camOtherShaders){ + newCamEffects.push(new ShaderFilter(i.shader)); + } + camOther.setFilters(newCamEffects); + default: + if(modchartSprites.exists(cam)) { + Reflect.setProperty(modchartSprites.get(cam),"shader",null); + } else if(modchartTexts.exists(cam)) { + Reflect.setProperty(modchartTexts.get(cam),"shader",null); + } else { + var OBJ = Reflect.getProperty(PlayState.instance,cam); + Reflect.setProperty(OBJ,"shader", null); + } + + } + + + } + + + + public function clearShaderFromCamera(cam:String){ + + + switch(cam.toLowerCase()) { + case 'camhud' | 'hud': + camHUDShaders = []; + var newCamEffects:Array=[]; + camHUD.setFilters(newCamEffects); + case 'camother' | 'other': + camOtherShaders = []; + var newCamEffects:Array=[]; + camOther.setFilters(newCamEffects); + case 'camgame' | 'game': + camGameShaders = []; + var newCamEffects:Array=[]; + camGame.setFilters(newCamEffects); + default: + camGameShaders = []; + var newCamEffects:Array=[]; + camGame.setFilters(newCamEffects); + } + + + } + + public function getLuaObject(tag:String, text:Bool=true):FlxSprite { + if(modchartSprites.exists(tag)) return modchartSprites.get(tag); + if(text && modchartTexts.exists(tag)) return modchartTexts.get(tag); + if(variables.exists(tag)) return variables.get(tag); + return null; + } + + function startCharacterPos(char:Character, ?gfCheck:Bool = false) { + if(gfCheck && char.curCharacter.startsWith('gf')) { //IF DAD IS GIRLFRIEND, HE GOES TO HER POSITION + char.setPosition(GF_X, GF_Y); + char.scrollFactor.set(0.95, 0.95); + char.danceEveryNumBeats = 2; + } + char.x += char.positionArray[0]; + char.y += char.positionArray[1]; + } + + public function startVideo(name:String) + { + #if VIDEOS_ALLOWED + inCutscene = true; + + var filepath:String = Paths.video(name); + #if sys + if(!FileSystem.exists(filepath)) + #else + if(!OpenFlAssets.exists(filepath)) + #end + { + FlxG.log.warn('Couldnt find video file: ' + name); + startAndEnd(); + return; + } + + var video:MP4Handler = new MP4Handler(); + #if (hxCodec < "3.0.0") + video.playVideo(filepath); + video.finishCallback = function() + { + startAndEnd(); + return; + } + #else + video.play(filepath); + video.onEndReached.add(function(){ + video.dispose(); + startAndEnd(); + return; + }); + #end + #else + FlxG.log.warn('Platform not supported!'); + startAndEnd(); + return; + #end + } + + function startAndEnd() + { + if(endingSong) + endSong(); + else + startCountdown(); + } + + var dialogueCount:Int = 0; + public var psychDialogue:DialogueBoxPsych; + //You don't have to add a song, just saying. You can just do "startDialogue(dialogueJson);" and it should work + public function startDialogue(dialogueFile:DialogueFile, ?song:String = null):Void + { + // TO DO: Make this more flexible, maybe? + if(psychDialogue != null) return; + + if(dialogueFile.dialogue.length > 0) { + inCutscene = true; + precacheList.set('dialogue', 'sound'); + precacheList.set('dialogueClose', 'sound'); + psychDialogue = new DialogueBoxPsych(dialogueFile, song); + psychDialogue.scrollFactor.set(); + if(endingSong) { + psychDialogue.finishThing = function() { + psychDialogue = null; + endSong(); + } + } else { + psychDialogue.finishThing = function() { + psychDialogue = null; + startCountdown(); + } + } + psychDialogue.nextDialogueThing = startNextDialogue; + psychDialogue.skipDialogueThing = skipDialogue; + psychDialogue.cameras = [camHUD]; + add(psychDialogue); + } else { + FlxG.log.warn('Your dialogue file is badly formatted!'); + if(endingSong) { + endSong(); + } else { + startCountdown(); + } + } + } + + public function changeTheSettingsBitch() { + healthGain = ClientPrefs.getGameplaySetting('healthgain', 1); + healthLoss = ClientPrefs.getGameplaySetting('healthloss', 1); + hpDrainLevel = ClientPrefs.getGameplaySetting('drainlevel', 1); + instakillOnMiss = ClientPrefs.getGameplaySetting('instakill', false); + sickOnly = ClientPrefs.getGameplaySetting('onlySicks', false); + practiceMode = ClientPrefs.getGameplaySetting('practice', false); + cpuControlled = ClientPrefs.getGameplaySetting('botplay', false); + opponentChart = ClientPrefs.getGameplaySetting('opponentplay', false); + bothsides = ClientPrefs.getGameplaySetting('bothSides', false); + trollingMode = ClientPrefs.getGameplaySetting('thetrollingever', false); + opponentDrain = ClientPrefs.getGameplaySetting('opponentdrain', false); + randomMode = ClientPrefs.getGameplaySetting('randommode', false); + flip = ClientPrefs.getGameplaySetting('flip', false); + stairs = ClientPrefs.getGameplaySetting('stairmode', false); + waves = ClientPrefs.getGameplaySetting('wavemode', false); + oneK = ClientPrefs.getGameplaySetting('onekey', false); + randomSpeedThing = ClientPrefs.getGameplaySetting('randomspeed', false); + trollingMode = ClientPrefs.getGameplaySetting('thetrollingever', false); + jackingtime = ClientPrefs.getGameplaySetting('jacks', 0); + playbackRate = ClientPrefs.getGameplaySetting('songspeed', 1); + songSpeedType = ClientPrefs.getGameplaySetting('scrolltype','multiplicative'); + + switch(songSpeedType) + { + case "multiplicative": + songSpeed = SONG.speed * ClientPrefs.getGameplaySetting('scrollspeed', 1); + case "constant": + songSpeed = ClientPrefs.getGameplaySetting('scrollspeed', 1); + } + } + + function schoolIntro(?dialogueBox:DialogueBox):Void + { + inCutscene = true; + var black:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); + black.scrollFactor.set(); + add(black); + + var red:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, 0xFFff1b31); + red.scrollFactor.set(); + + var senpaiEvil:FlxSprite = new FlxSprite(); + senpaiEvil.frames = Paths.getSparrowAtlas('weeb/senpaiCrazy'); + senpaiEvil.animation.addByPrefix('idle', 'Senpai Pre Explosion', 24, false); + senpaiEvil.setGraphicSize(Std.int(senpaiEvil.width * 6)); + senpaiEvil.scrollFactor.set(); + senpaiEvil.updateHitbox(); + senpaiEvil.screenCenter(); + senpaiEvil.x += 300; + + var songName:String = Paths.formatToSongPath(SONG.song); + if (songName == 'roses' || songName == 'thorns') + { + remove(black); + + if (songName == 'thorns') + { + add(red); + camHUD.visible = false; + } + } + + new FlxTimer().start(0.3, function(tmr:FlxTimer) + { + black.alpha -= 0.15; + + if (black.alpha > 0) + { + tmr.reset(0.3); + } + else + { + if (dialogueBox != null) + { + if (Paths.formatToSongPath(SONG.song) == 'thorns') + { + add(senpaiEvil); + senpaiEvil.alpha = 0; + new FlxTimer().start(0.3, function(swagTimer:FlxTimer) + { + senpaiEvil.alpha += 0.15; + if (senpaiEvil.alpha < 1) + { + swagTimer.reset(); + } + else + { + senpaiEvil.animation.play('idle'); + FlxG.sound.play(Paths.sound('Senpai_Dies'), 1, false, null, true, function() + { + remove(senpaiEvil); + remove(red); + FlxG.camera.fade(FlxColor.WHITE, 0.01, true, function() + { + add(dialogueBox); + camHUD.visible = true; + }, true); + }); + new FlxTimer().start(3.2, function(deadTime:FlxTimer) + { + FlxG.camera.fade(FlxColor.WHITE, 1.6, false); + }); + } + }); + } + else + { + add(dialogueBox); + } + } + else + startCountdown(); + + remove(black); + } + }); + } + + function camPanRoutine(anim:String = 'singUP', who:String = 'bf'):Void { + if (SONG.notes[curSection] != null) + { + var fps:Float = FlxG.updateFramerate; + final bfCanPan:Bool = SONG.notes[curSection].mustHitSection; + final dadCanPan:Bool = !SONG.notes[curSection].mustHitSection; + var clear:Bool = false; + switch (who) { + case 'bf': clear = bfCanPan; + case 'oppt': clear = dadCanPan; + } + //FlxG.elapsed is stinky poo poo for this, it just makes it look jank as fuck + if (clear) { + if (fps == 0) fps = 1; + switch (anim.split('-')[0]) + { + case 'singUP': moveCamTo[1] = -40*ClientPrefs.panIntensity*240/fps; + case 'singDOWN': moveCamTo[1] = 40*ClientPrefs.panIntensity*240/fps; + case 'singLEFT': moveCamTo[0] = -40*ClientPrefs.panIntensity*240/fps; + case 'singRIGHT': moveCamTo[0] = 40*ClientPrefs.panIntensity*240/fps; + } + } + } + } + + + function tankIntro() + { + var cutsceneHandler:CutsceneHandler = new CutsceneHandler(); + + var songName:String = Paths.formatToSongPath(SONG.song); + dadGroup.alpha = 0.00001; + camHUD.visible = false; + //inCutscene = true; //this would stop the camera movement, oops + + var tankman:FlxSprite = new FlxSprite(-20, 320); + tankman.frames = Paths.getSparrowAtlas('cutscenes/' + songName); + tankman.antialiasing = ClientPrefs.globalAntialiasing; + addBehindDad(tankman); + cutsceneHandler.push(tankman); + + var tankman2:FlxSprite = new FlxSprite(16, 312); + tankman2.antialiasing = ClientPrefs.globalAntialiasing; + tankman2.alpha = 0.000001; + cutsceneHandler.push(tankman2); + var gfDance:FlxSprite = new FlxSprite(gf.x - 107, gf.y + 140); + gfDance.antialiasing = ClientPrefs.globalAntialiasing; + cutsceneHandler.push(gfDance); + var gfCutscene:FlxSprite = new FlxSprite(gf.x - 104, gf.y + 122); + gfCutscene.antialiasing = ClientPrefs.globalAntialiasing; + cutsceneHandler.push(gfCutscene); + var picoCutscene:FlxSprite = new FlxSprite(gf.x - 849, gf.y - 264); + picoCutscene.antialiasing = ClientPrefs.globalAntialiasing; + cutsceneHandler.push(picoCutscene); + var boyfriendCutscene:FlxSprite = new FlxSprite(boyfriend.x + 5, boyfriend.y + 20); + boyfriendCutscene.antialiasing = ClientPrefs.globalAntialiasing; + cutsceneHandler.push(boyfriendCutscene); + + cutsceneHandler.finishCallback = function() + { + var timeForStuff:Float = Conductor.crochet / 1000 * 4.5; + FlxG.sound.music.fadeOut(timeForStuff); + FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom}, timeForStuff, {ease: FlxEase.quadInOut}); + moveCamera(true); + startCountdown(); + + dadGroup.alpha = 1; + camHUD.visible = true; + boyfriend.animation.finishCallback = null; + gf.animation.finishCallback = null; + gf.dance(); + }; + + camFollow.set(dad.x + 280, dad.y + 170); + switch(songName) + { + case 'ugh': + cutsceneHandler.endTime = 12; + cutsceneHandler.music = 'DISTORTO'; + precacheList.set('wellWellWell', 'sound'); + precacheList.set('killYou', 'sound'); + precacheList.set('bfBeep', 'sound'); + + var wellWellWell:FlxSound = new FlxSound().loadEmbedded(Paths.sound('wellWellWell')); + FlxG.sound.list.add(wellWellWell); + + tankman.animation.addByPrefix('wellWell', 'TANK TALK 1 P1', 24, false); + tankman.animation.addByPrefix('killYou', 'TANK TALK 1 P2', 24, false); + tankman.animation.play('wellWell', true); + FlxG.camera.zoom *= 1.2; + + // Well well well, what do we got here? + cutsceneHandler.timer(0.1, function() + { + wellWellWell.play(true); + }); + + // Move camera to BF + cutsceneHandler.timer(3, function() + { + camFollow.x += 750; + camFollow.y += 100; + }); + + // Beep! + cutsceneHandler.timer(4.5, function() + { + boyfriend.playAnim('singUP', true); + boyfriend.specialAnim = true; + FlxG.sound.play(Paths.sound('bfBeep')); + }); + + // Move camera to Tankman + cutsceneHandler.timer(6, function() + { + camFollow.x -= 750; + camFollow.y -= 100; + + // We should just kill you but... what the hell, it's been a boring day... let's see what you've got! + tankman.animation.play('killYou', true); + FlxG.sound.play(Paths.sound('killYou')); + }); + + case 'guns': + cutsceneHandler.endTime = 11.5; + cutsceneHandler.music = 'DISTORTO'; + tankman.x += 40; + tankman.y += 10; + precacheList.set('tankSong2', 'sound'); + + var tightBars:FlxSound = new FlxSound().loadEmbedded(Paths.sound('tankSong2')); + FlxG.sound.list.add(tightBars); + + tankman.animation.addByPrefix('tightBars', 'TANK TALK 2', 24, false); + tankman.animation.play('tightBars', true); + boyfriend.animation.curAnim.finish(); + + cutsceneHandler.onStart = function() + { + tightBars.play(true); + FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom * 1.2}, 4, {ease: FlxEase.quadInOut}); + FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom * 1.2 * 1.2}, 0.5, {ease: FlxEase.quadInOut, startDelay: 4}); + FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom * 1.2}, 1, {ease: FlxEase.quadInOut, startDelay: 4.5}); + }; + + cutsceneHandler.timer(4, function() + { + gf.playAnim('sad', true); + gf.animation.finishCallback = function(name:String) + { + gf.playAnim('sad', true); + }; + }); + + case 'stress': + cutsceneHandler.endTime = 35.5; + tankman.x -= 54; + tankman.y -= 14; + gfGroup.alpha = 0.00001; + boyfriendGroup.alpha = 0.00001; + camFollow.set(dad.x + 400, dad.y + 170); + FlxTween.tween(FlxG.camera, {zoom: 0.9 * 1.2}, 1, {ease: FlxEase.quadInOut}); + foregroundSprites.forEach(function(spr:BGSprite) + { + spr.y += 100; + }); + precacheList.set('stressCutscene', 'sound'); + + tankman2.frames = Paths.getSparrowAtlas('cutscenes/stress2'); + addBehindDad(tankman2); + + if (!ClientPrefs.lowQuality) + { + gfDance.frames = Paths.getSparrowAtlas('characters/gfTankmen'); + gfDance.animation.addByPrefix('dance', 'GF Dancing at Gunpoint', 24, true); + gfDance.animation.play('dance', true); + addBehindGF(gfDance); + } + + gfCutscene.frames = Paths.getSparrowAtlas('cutscenes/stressGF'); + gfCutscene.animation.addByPrefix('dieBitch', 'GF STARTS TO TURN PART 1', 24, false); + gfCutscene.animation.addByPrefix('getRektLmao', 'GF STARTS TO TURN PART 2', 24, false); + gfCutscene.animation.play('dieBitch', true); + gfCutscene.animation.pause(); + addBehindGF(gfCutscene); + if (!ClientPrefs.lowQuality) + { + gfCutscene.alpha = 0.00001; + } + + picoCutscene.frames = AtlasFrameMaker.construct('cutscenes/stressPico'); + picoCutscene.animation.addByPrefix('anim', 'Pico Badass', 24, false); + addBehindGF(picoCutscene); + picoCutscene.alpha = 0.00001; + + boyfriendCutscene.frames = Paths.getSparrowAtlas('characters/BOYFRIEND'); + boyfriendCutscene.animation.addByPrefix('idle', 'BF idle dance', 24, false); + boyfriendCutscene.animation.play('idle', true); + boyfriendCutscene.animation.curAnim.finish(); + addBehindBF(boyfriendCutscene); + + var cutsceneSnd:FlxSound = new FlxSound().loadEmbedded(Paths.sound('stressCutscene')); + FlxG.sound.list.add(cutsceneSnd); + + tankman.animation.addByPrefix('godEffingDamnIt', 'TANK TALK 3', 24, false); + tankman.animation.play('godEffingDamnIt', true); + + var calledTimes:Int = 0; + var zoomBack:Void->Void = function() + { + var camPosX:Float = 630; + var camPosY:Float = 425; + camFollow.set(camPosX, camPosY); + camFollowPos.setPosition(camPosX, camPosY); + FlxG.camera.zoom = 0.8; + cameraSpeed = 1; + + calledTimes++; + if (calledTimes > 1) + { + foregroundSprites.forEach(function(spr:BGSprite) + { + spr.y -= 100; + }); + } + } + + cutsceneHandler.onStart = function() + { + cutsceneSnd.play(true); + }; + + cutsceneHandler.timer(15.2, function() + { + FlxTween.tween(camFollow, {x: 650, y: 300}, 1, {ease: FlxEase.sineOut}); + FlxTween.tween(FlxG.camera, {zoom: 0.9 * 1.2 * 1.2}, 2.25, {ease: FlxEase.quadInOut}); + + gfDance.visible = false; + gfCutscene.alpha = 1; + gfCutscene.animation.play('dieBitch', true); + gfCutscene.animation.finishCallback = function(name:String) + { + if(name == 'dieBitch') //Next part + { + gfCutscene.animation.play('getRektLmao', true); + gfCutscene.offset.set(224, 445); + } + else + { + gfCutscene.visible = false; + picoCutscene.alpha = 1; + picoCutscene.animation.play('anim', true); + + boyfriendGroup.alpha = 1; + boyfriendCutscene.visible = false; + boyfriend.playAnim('bfCatch', true); + boyfriend.animation.finishCallback = function(name:String) + { + if(name != 'idle') + { + boyfriend.playAnim('idle', true); + boyfriend.animation.curAnim.finish(); //Instantly goes to last frame + } + }; + + picoCutscene.animation.finishCallback = function(name:String) + { + picoCutscene.visible = false; + gfGroup.alpha = 1; + picoCutscene.animation.finishCallback = null; + }; + gfCutscene.animation.finishCallback = null; + } + }; + }); + + cutsceneHandler.timer(17.5, function() + { + zoomBack(); + }); + + cutsceneHandler.timer(19.5, function() + { + tankman2.animation.addByPrefix('lookWhoItIs', 'TANK TALK 3', 24, false); + tankman2.animation.play('lookWhoItIs', true); + tankman2.alpha = 1; + tankman.visible = false; + }); + + cutsceneHandler.timer(20, function() + { + camFollow.set(dad.x + 500, dad.y + 170); + }); + + cutsceneHandler.timer(31.2, function() + { + boyfriend.playAnim('singUPmiss', true); + boyfriend.animation.finishCallback = function(name:String) + { + if (name == 'singUPmiss') + { + boyfriend.playAnim('idle', true); + boyfriend.animation.curAnim.finish(); //Instantly goes to last frame + } + }; + + camFollow.set(boyfriend.x + 280, boyfriend.y + 200); + cameraSpeed = 12; + FlxTween.tween(FlxG.camera, {zoom: 0.9 * 1.2 * 1.2}, 0.25, {ease: FlxEase.elasticOut}); + }); + + cutsceneHandler.timer(32.2, function() + { + zoomBack(); + }); + } + } + + var startTimer:FlxTimer; + var finishTimer:FlxTimer = null; + + // For being able to mess with the sprites on Lua + public var countdownReady:FlxSprite; + public var countdownSet:FlxSprite; + public var countdownGo:FlxSprite; + public static var startOnTime:Float = 0; + + function cacheCountdown() + { + var introAssets:Map> = new Map>(); + introAssets.set('default', ['ready', 'set', 'go']); + introAssets.set('pixel', ['pixelUI/ready-pixel', 'pixelUI/set-pixel', 'pixelUI/date-pixel']); + + var introAlts:Array = introAssets.get('default'); + if (isPixelStage) introAlts = introAssets.get('pixel'); + + for (asset in introAlts) + Paths.image(asset); + + Paths.sound('intro3' + introSoundsSuffix); + Paths.sound('intro2' + introSoundsSuffix); + Paths.sound('intro1' + introSoundsSuffix); + Paths.sound('introGo' + introSoundsSuffix); + + } + + private function updateCompactNumbers():Void + { + compactUpdateFrame++; + compactCombo = formatCompactNumber(combo); + compactMaxCombo = formatCompactNumber(maxCombo); + compactScore = formatCompactNumber(songScore); + compactMisses = formatCompactNumberInt(songMisses); + compactNPS = formatCompactNumber(nps); + compactTotalPlays = formatCompactNumber(totalNotesPlayed); + } + + public static function formatCompactNumber(number:Float):String //this entire function is ai generated LMAO + { + var suffixes:Array = ['', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quattuordecillion', 'quindecillion', 'sexdecillion', 'septendecillion', 'octodecillion', 'novemdecillion', 'vigintillion', 'unvigintillion', 'duovigintillion', 'trevigintillion', 'quattuorvigintillion', 'quinvigintillion', 'sesvigintillion', 'septemvigintillion', 'octovigintillion', 'novemvigintillion', 'trigintillion', 'untrigintillion', 'duotrigintillion', 'trestrigintillion', 'quattuortrigintillion', 'quintrigintillion', 'sestrigintillion', 'septentrigintillion', 'octotrigintillion', 'noventrigintillion', 'quadragintillion', 'unquadragintillion', 'duoquadragintillion', 'trequadragintillion', 'quattuorquadragintillion', 'quinquadragintillion', 'sesquadragintillion', 'septenquadragintillion', 'octoquadragintillion', 'novenquadragintillion', 'quinquagintillion', 'unquinquagintillion', 'duoquinquagintillion', 'trequinquagintillion', 'quattuorquinquagintillion', 'quinquinquagintillion', 'sesquinquagintillion', 'septenquinquagintillion', 'octoquinquagintillion', 'novenquinquagintillion', 'sexagintillion', 'unsexagintillion', 'duosexagintillion', 'tresexagintillion', 'quattuorsexagintillion', 'quinsexagintillion', 'sesagintillion', 'septensexagintillion', 'octosexagintillion', 'novensexagintillion', 'septuagintillion', 'unseptuagintillion', 'duoseptuagintillion', 'treseptuagintillion', 'quattuorseptuagintillion', 'quinseptuagintillion', 'seseptuaintillion', 'septenseptuagintillion', 'octoseptuagintillion', 'novenseptuagintillion', 'octogintillion', 'unoctogintillion', 'duooctogintillion', 'tresoctogintillion', 'quattuoroctogintillion', 'quinoctogintillion', 'sesoctogintillion', 'septenoctogintillion', 'octooctogintillion', 'novenoctogintillion', 'nonagintillion', 'unnonagintillion', 'duononagintillion', 'tresnonagintillion', 'quattuornonagintillion', 'quinnonagintillion', 'sesnonagintillion', 'septennonagintillion', 'octononagintillion', 'novennonagintillion', 'centillion', 'uncentillion']; //Every 'illion' up to 10^308, taken straight from Conway's zillion number list + var magnitude:Int = 0; + var num:Float = number; + + while (num >= 1000.0 && magnitude < suffixes.length - 1) + { + num /= 1000.0; + magnitude++; + } + + // Use the floor value for the compact representation + var compactValue:Float = Math.floor(num * 100) / 100; + if (compactValue <= 0.001) { + return "0"; //Return 0 if compactValue = null + } else { + return compactValue + (magnitude == 0 ? "" : " ") + suffixes[magnitude]; + } + } + public static function formatCompactNumberInt(number:Int):String //this entire function is ai generated LMAO + { + var suffixes:Array = ['', 'thousand', 'million', 'billion']; //Illions up to billion, nothing higher because integers can't go past 2,147,483,647 + var magnitude:Int = 0; + var num:Float = number; + + while (num >= 1000.0 && magnitude < suffixes.length - 1) + { + num /= 1000.0; + magnitude++; + } + + // Use the floor value for the compact representation + var compactValue:Float = Math.floor(num * 100) / 100; + if (compactValue <= 0.001) { + return "0"; //Return 0 if compactValue = null + } else { + return compactValue + (magnitude == 0 ? "" : " ") + suffixes[magnitude]; + } + } + + + public function startCountdown():Void + { + if(startedCountdown) { + callOnLuas('onStartCountdown', []); + return; + } + + inCutscene = false; + var ret:Dynamic = callOnLuas('onStartCountdown', [], false); + + if (ClientPrefs.coolGameplay) + { + hueh231 = new FlxSprite(); + hueh231.frames = Paths.getSparrowAtlas('dokistuff/coolgameplay'); + hueh231.animation.addByPrefix('idle', 'Symbol', 24, true); + hueh231.animation.play('idle'); + hueh231.antialiasing = ClientPrefs.globalAntialiasing; + hueh231.scrollFactor.set(); + hueh231.setGraphicSize(Std.int(hueh231.width / FlxG.camera.zoom)); + hueh231.updateHitbox(); + hueh231.screenCenter(); + hueh231.cameras = [camGame]; + add(hueh231); + } + if (SONG.song.toLowerCase() == 'anti-cheat-song') + { + secretsong = new FlxSprite().loadGraphic(Paths.image('secretSong')); + secretsong.antialiasing = ClientPrefs.globalAntialiasing; + secretsong.scrollFactor.set(); + secretsong.setGraphicSize(Std.int(secretsong.width / FlxG.camera.zoom)); + secretsong.updateHitbox(); + secretsong.screenCenter(); + secretsong.cameras = [camGame]; + add(secretsong); + } + if (ClientPrefs.middleScroll || ClientPrefs.mobileMidScroll) + { + laneunderlayOpponent.alpha = 0; + laneunderlay.screenCenter(X); + } + + if(ret != FunkinLua.Function_Stop) { + if (skipCountdown || startOnTime > 0) skipArrowStartTween = true; + + #if android + androidControls.visible = !cpuControlled; //no need to have them visible if Botplay is on + #end + generateStaticArrows(0); + generateStaticArrows(1); + for (i in 0...opponentStrums.length) { + setOnLuas('defaultOpponentStrumX' + i, opponentStrums.members[i].x); + setOnLuas('defaultOpponentStrumY' + i, opponentStrums.members[i].y); + //if(ClientPrefs.middleScroll) opponentStrums.members[i].visible = false; + } + for (i in 0...playerStrums.length) { + setOnLuas('defaultPlayerStrumX' + i, playerStrums.members[i].x); + setOnLuas('defaultPlayerStrumY' + i, playerStrums.members[i].y); + } + /*for (i in 0...opponentStrums.length) { + setOnLuas('defaultOpponentStrumX' + i, opponentStrums.members[i].x); + setOnLuas('defaultOpponentStrumY' + i, opponentStrums.members[i].y); + //if(ClientPrefs.middleScroll) opponentStrums.members[i].visible = false; + } + */ + + startedCountdown = true; + Conductor.songPosition = -Conductor.crochet * 5; + setOnLuas('startedCountdown', true); + callOnLuas('onCountdownStarted', []); + + var swagCounter:Int = 0; + + if(startOnTime < 0) startOnTime = 0; + + if (startOnTime > 0) { + clearNotesBefore(startOnTime); + setSongTime(startOnTime - 350); + return; + } + else if (skipCountdown) + { + setSongTime(0); + return; + } + + startTimer = new FlxTimer().start(Conductor.crochet / 1000 / playbackRate, function(tmr:FlxTimer) + { + if (ClientPrefs.charsAndBG) { + if (gf != null && tmr.loopsLeft % Math.round(gfSpeed * gf.danceEveryNumBeats) == 0 && gf.animation.curAnim != null && !gf.animation.curAnim.name.startsWith("sing") && !gf.stunned) + { + gf.dance(); + } + if (tmr.loopsLeft % boyfriend.danceEveryNumBeats == 0 && boyfriend.animation.curAnim != null && !boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.stunned) + { + boyfriend.dance(); + } + if (tmr.loopsLeft % dad.danceEveryNumBeats == 0 && dad.animation.curAnim != null && !dad.animation.curAnim.name.startsWith('sing') && !dad.stunned) + { + dad.dance(); + } + } + + var introAssets:Map> = new Map>(); + introAssets.set('default', ['ready', 'set', 'go']); + introAssets.set('pixel', ['pixelUI/ready-pixel', 'pixelUI/set-pixel', 'pixelUI/date-pixel']); + + var introAlts:Array = introAssets.get('default'); + var antialias:Bool = ClientPrefs.globalAntialiasing; + if(isPixelStage) { + introAlts = introAssets.get('pixel'); + antialias = false; + } + + // head bopping for bg characters on Mall + if(curStage == 'mall') { + if(!ClientPrefs.lowQuality) + upperBoppers.dance(true); + + bottomBoppers.dance(true); + santa.dance(true); + } + + switch (swagCounter) + { + case 0: + FlxG.sound.play(Paths.sound('intro3' + introSoundsSuffix), 0.6); + case 1: + countdownReady = new FlxSprite().loadGraphic(Paths.image(introAlts[0])); + countdownReady.cameras = [camHUD]; + countdownReady.scrollFactor.set(); + countdownReady.updateHitbox(); + + if (PlayState.isPixelStage) + countdownReady.setGraphicSize(Std.int(countdownReady.width * daPixelZoom)); + + countdownReady.screenCenter(); + countdownReady.antialiasing = antialias; + insert(members.indexOf(notes), countdownReady); + FlxTween.tween(countdownReady, {/*y: countdownReady.y + 100,*/ alpha: 0}, Conductor.crochet / 1000 / playbackRate, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + remove(countdownReady); + countdownReady.destroy(); + } + }); + FlxG.sound.play(Paths.sound('intro2' + introSoundsSuffix), 0.6); + case 2: + countdownSet = new FlxSprite().loadGraphic(Paths.image(introAlts[1])); + countdownSet.cameras = [camHUD]; + countdownSet.scrollFactor.set(); + + if (PlayState.isPixelStage) + countdownSet.setGraphicSize(Std.int(countdownSet.width * daPixelZoom)); + + countdownSet.screenCenter(); + countdownSet.antialiasing = antialias; + insert(members.indexOf(notes), countdownSet); + FlxTween.tween(countdownSet, {/*y: countdownSet.y + 100,*/ alpha: 0}, Conductor.crochet / 1000 / playbackRate, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + remove(countdownSet); + countdownSet.destroy(); + } + }); + FlxG.sound.play(Paths.sound('intro1' + introSoundsSuffix), 0.6); + case 3: + countdownGo = new FlxSprite().loadGraphic(Paths.image(introAlts[2])); + countdownGo.cameras = [camHUD]; + countdownGo.scrollFactor.set(); + + if (PlayState.isPixelStage) + countdownGo.setGraphicSize(Std.int(countdownGo.width * daPixelZoom)); + + countdownGo.updateHitbox(); + + countdownGo.screenCenter(); + countdownGo.antialiasing = antialias; + insert(members.indexOf(notes), countdownGo); + FlxTween.tween(countdownGo, {/*y: countdownGo.y + 100,*/ alpha: 0}, Conductor.crochet / 1000 / playbackRate, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + remove(countdownGo); + countdownGo.destroy(); + } + }); + FlxG.sound.play(Paths.sound('introGo' + introSoundsSuffix), 0.6); + case 4: + if (SONG.songCredit != null) + { + var creditsPopup:CreditsPopUp = new CreditsPopUp(FlxG.width, 200); + creditsPopup.camera = camHUD; + creditsPopup.scrollFactor.set(); + creditsPopup.x = creditsPopup.width * -1; + add(creditsPopup); + + FlxTween.tween(creditsPopup, {x: 0}, 0.5, {ease: FlxEase.backOut, onComplete: function(tweeen:FlxTween) + { + FlxTween.tween(creditsPopup, {x: creditsPopup.width * -1} , 1, {ease: FlxEase.backIn, onComplete: function(tween:FlxTween) + { + creditsPopup.destroy(); + }, startDelay: 3}); + }}); + } + } + + notes.forEachAlive(function(note:Note) { + if(ClientPrefs.opponentStrums || !ClientPrefs.opponentStrums && ClientPrefs.mobileMidScroll || ClientPrefs.middleScroll || !note.mustPress) + { + note.alpha *= 0.35; + } + if(ClientPrefs.opponentStrums || !ClientPrefs.opponentStrums && ClientPrefs.mobileMidScroll || note.mustPress) + { + note.copyAlpha = false; + note.alpha = note.multAlpha; + if(ClientPrefs.middleScroll && !note.mustPress) { + note.alpha *= 0.35; + } + if(ClientPrefs.mobileMidScroll && !note.mustPress) { + note.alpha *= 0.35; + } + } + }); + callOnLuas('onCountdownTick', [swagCounter]); + + swagCounter += 1; + // generateSong('fresh'); + }, 5); + } + } + + public function addBehindGF(obj:FlxObject) + { + insert(members.indexOf(gfGroup), obj); + } + public function addBehindBF(obj:FlxObject) + { + insert(members.indexOf(boyfriendGroup), obj); + } + public function addBehindDad (obj:FlxObject) + { + insert(members.indexOf(dadGroup), obj); + } + + public function clearNotesBefore(time:Float) + { + var i:Int = unspawnNotes.length - 1; + while (i >= 0) { + var daNote:Note = unspawnNotes[i]; + if(daNote.strumTime - 350 < time) + { + daNote.active = false; + daNote.visible = false; + daNote.ignoreNote = true; + + if (shouldKillNotes) { + daNote.kill(); + } + //unspawnNotes.remove(daNote); + if (shouldKillNotes) { + daNote.destroy(); + } + } + --i; + } + + i = notes.length - 1; + while (i >= 0) { + var daNote:Note = notes.members[i]; + if(daNote.strumTime - 350 < time) + { + daNote.active = false; + daNote.visible = false; + daNote.ignoreNote = true; + + if (shouldKillNotes) { + daNote.kill(); + } + notes.remove(daNote, true); + if (shouldKillNotes) { + daNote.destroy(); + } + } + --i; + } + } + + public function updateScore(miss:Bool = false) + { + if (ClientPrefs.hudType == 'Kade Engine') + { + scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Combo Breaks: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) + + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Accuracy: ' + Highscore.floorDecimal(ratingPercent * 100, 2) + '%' + + ' | ' + ratingFC + ratingCool; + if (cpuControlled && !ClientPrefs.communityGameBot) + { + scoreTxt.text = 'Bot Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Botplay Mode '; + } + } + if (ClientPrefs.hudType == "Mic'd Up" || ClientPrefs.hudType == 'Box Funkin') + { + comboTxt.text = "Combo: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo); + scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : ''); + missTxt.text = "Misses: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses); + accuracyTxt.text = "Accuracy: " + Highscore.floorDecimal(ratingPercent * 100, 2) + "% | " + ratingFC + " |" + ratingCool; + npsTxt.text = "\n" + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : ''); + if (cpuControlled && !ClientPrefs.communityGameBot) + { + scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : ''); + missTxt.text = "Bot Combo: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo); + accuracyTxt.text = "" + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : ''); + npsTxt.text = "Botplay Mode"; + } + } + if (ClientPrefs.hudType == "Doki Doki+") + { + scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Breaks: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) + + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Accuracy: ' + Highscore.floorDecimal(ratingPercent * 100, 2) + '%' + + ' | ' + ratingFC + ratingCool; + if (cpuControlled && !ClientPrefs.communityGameBot) + { + scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Botplay Mode '; + } + } + if (ClientPrefs.hudType == "Dave and Bambi") + { + scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) + + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Accuracy: ' + Highscore.floorDecimal(ratingPercent * 100, 2) + '%' + + ' | ' + ratingFC; + if (cpuControlled && !ClientPrefs.communityGameBot) + { + scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Botplay Mode '; + } + } + if (ClientPrefs.hudType == "Psych Engine") + { + scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) + + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Rating: ' + ratingName + + (ratingName != '?' ? ' (${Highscore.floorDecimal(ratingPercent * 100, 2)}%) - $ratingFC' : ''); + if (cpuControlled && !ClientPrefs.communityGameBot) + { + scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | funny botplay mode!!!!!'; + } + } + if (ClientPrefs.hudType == "JS Engine") + { + scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(shownScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) + + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Rating: ' + ratingName + + (ratingName != '?' ? ' (${Highscore.floorDecimal(ratingPercent * 100, 2)}%) - $ratingFC' : ''); + if (cpuControlled && !ClientPrefs.communityGameBot) + { + scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(shownScore, false) : compactScore) + + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Botplay Mode'; + } + } + if (ClientPrefs.hudType == "Leather Engine") + { + scoreTxt.text = '< Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + + ' ~ Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) + + ' ~ Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' ~ NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' ~ Rating: ' + ratingName + + (ratingName != '?' ? ' (${Highscore.floorDecimal(ratingPercent * 100, 2)}%) ~ $ratingFC' : ''); + if (cpuControlled && !ClientPrefs.communityGameBot) + { + scoreTxt.text = "< Bot Score: " + FlxStringUtil.formatMoney(songScore, false) + + ' ~ Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' ~ Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' ~ Botplay Mode >'; + } + } + if (ClientPrefs.hudType == "Tails Gets Trolled V4") + { + scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + + ' | Misses: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) + + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Rating: ' + ratingName + + (ratingName != '?' ? ' (${Highscore.floorDecimal(ratingPercent * 100, 2)}%) - $ratingFC' : ''); + if (cpuControlled && !ClientPrefs.communityGameBot) + { + scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | funny botplay mode!!!!'; + } + } + if (ClientPrefs.hudType == "VS Impostor") + { + scoreTxt.text = 'Score: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Combo Breaks: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songMisses, false) : compactMisses) + + ' | Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Accuracy: ' + Highscore.floorDecimal(ratingPercent * 100, 2) + '%' + + ratingFC; + if (cpuControlled && !ClientPrefs.communityGameBot) + { + scoreTxt.text = "Bot Score: " + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(songScore, false) : compactScore) + (ClientPrefs.showMaxScore ? ' / ' + FlxStringUtil.formatMoney(maxScore, false) : '') + + ' | Bot Combo: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + + (ClientPrefs.showNPS ? ' | Bot NPS: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(nps, false) : compactNPS) : '') + + ' | Botplay Mode'; + } + } + if (ClientPrefs.healthDisplay) scoreTxt.text += ' | Health: ' + FlxMath.roundDecimal(health * 50, 2) + '%'; + + /*if(ClientPrefs.scoreZoom && !miss && !cpuControlled) + { + if(scoreTxtTween != null) { + scoreTxtTween.cancel(); + } + scoreTxt.scale.x = 1.075; + scoreTxt.scale.y = 1.075; + scoreTxtTween = FlxTween.tween(scoreTxt.scale, {x: 1, y: 1}, 0.2, { + onComplete: function(twn:FlxTween) { + scoreTxtTween = null; + } + }); + } moving this to popupscore so that it doesn't just break scoretxt*/ + callOnLuas('onUpdateScore', [miss]); + scoreTxtUpdateFrame++; + } + + public function setSongTime(time:Float) + { + if(time < 0) time = 0; + + if (ClientPrefs.songLoading) FlxG.sound.music.pause(); + if (ClientPrefs.songLoading) vocals.pause(); + + if (ClientPrefs.songLoading) FlxG.sound.music.time = time; + if (ClientPrefs.songLoading) FlxG.sound.music.pitch = playbackRate; + if (ClientPrefs.songLoading) FlxG.sound.music.play(); + + if (Conductor.songPosition <= vocals.length && ClientPrefs.songLoading) + { + vocals.time = time; + vocals.pitch = playbackRate; + } + if (ClientPrefs.songLoading) vocals.play(); + Conductor.songPosition = time; + songTime = time; + } + + function startNextDialogue() { + dialogueCount++; + callOnLuas('onNextDialogue', [dialogueCount]); + } + + function skipDialogue() { + callOnLuas('onSkipDialogue', [dialogueCount]); + } + + var previousFrameTime:Int = 0; + var lastReportedPlayheadPosition:Int = 0; + var songTime:Float = 0; + + function startSong():Void + { + startingSong = false; + + previousFrameTime = FlxG.game.ticks; + lastReportedPlayheadPosition = 0; + if (ClientPrefs.songLoading) + { + FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false); + FlxG.sound.music.pitch = playbackRate; + if (!trollingMode && SONG.song.toLowerCase() != 'anti-cheat-song' && SONG.song.toLowerCase() != 'desert bus') + { + FlxG.sound.music.onComplete = finishSong.bind(); + } + /* + if (trollingMode && ClientPrefs.trollMaxSpeed == 'Highest') + { + FlxG.sound.music.onComplete = loopSongHighest.bind(); + } + if (trollingMode && ClientPrefs.trollMaxSpeed == 'High') + { + FlxG.sound.music.onComplete = loopSongHigh.bind(); + } + if (trollingMode && ClientPrefs.trollMaxSpeed == 'Medium') + { + FlxG.sound.music.onComplete = loopSongMedium.bind(); + } + if (trollingMode && ClientPrefs.trollMaxSpeed == 'Low') + { + FlxG.sound.music.onComplete = loopSongLow.bind(); + } + if (trollingMode && ClientPrefs.trollMaxSpeed == 'Lower') + { + FlxG.sound.music.onComplete = loopSongLower.bind(); + } + if (trollingMode && ClientPrefs.trollMaxSpeed == 'Lowest') + { + FlxG.sound.music.onComplete = loopSongLowest.bind(); + } + if (trollingMode && ClientPrefs.trollMaxSpeed == 'Disabled') + { + FlxG.sound.music.onComplete = loopSongNoLimit.bind(); + } + */ + vocals.play(); + } + + if(startOnTime > 0) + { + setSongTime(startOnTime - 500); + } + startOnTime = 0; + + if(paused) { + //trace('Oopsie doopsie! Paused sound'); + if (ClientPrefs.songLoading) + { + FlxG.sound.music.pause(); + vocals.pause(); + } + } + var curTime:Float = Conductor.songPosition - ClientPrefs.noteOffset; + songPercent = (curTime / songLength); + + + // Song duration in a float, useful for the time left feature + if (ClientPrefs.lengthIntro && ClientPrefs.songLoading) FlxTween.tween(this, {songLength: FlxG.sound.music.length}, 1, {ease: FlxEase.expoOut}); + if (!ClientPrefs.lengthIntro && ClientPrefs.songLoading) songLength = FlxG.sound.music.length; //so that the timer won't just appear as 0 + if (ClientPrefs.timeBarType != 'Disabled') { + timeBar.scale.x = 0.01; + timeBarBG.scale.x = 0.01; + FlxTween.tween(timeBar, {alpha: 1, "scale.x": 1}, 1, {ease: FlxEase.expoOut}); + FlxTween.tween(timeBarBG, {alpha: 1, "scale.x": 1}, 1, {ease: FlxEase.expoOut}); + FlxTween.tween(timeTxt, {alpha: 1}, 0.5, {ease: FlxEase.circOut}); + } + FlxTween.tween(timePercentTxt, {alpha: 1}, 0.5, {ease: FlxEase.circOut}); + + + + switch(curStage) + { + case 'tank': + if(!ClientPrefs.lowQuality) tankWatchtower.dance(); + foregroundSprites.forEach(function(spr:BGSprite) + { + spr.dance(); + }); + } + + #if desktop + if (cpuControlled) detailsText = detailsText + ' (using a bot)'; + // Updating Discord Rich Presence (with Time Left) + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter(), true, songLength); + #end + setOnLuas('songLength', songLength); + callOnLuas('onSongStart', []); + } + public function lerpSongSpeed(num:Float, time:Float):Void + { + FlxTween.num(playbackRate, num, time, {onUpdate: function(tween:FlxTween){ + var ting = FlxMath.lerp(playbackRate, num, tween.percent); + if (ting != 0) //divide by 0 is a verry bad + playbackRate = ting; //why cant i just tween a variable + + if (ClientPrefs.songLoading) FlxG.sound.music.time = Conductor.songPosition; + if (ClientPrefs.songLoading && !ClientPrefs.noSyncing) resyncVocals(); + }}); + } + + var debugNum:Int = 0; + var stair:Int = 0; + private var noteTypeMap:Map = new Map(); + private var eventPushedMap:Map = new Map(); + private function generateSong(dataPath:String):Void + { + var startTime = Sys.time(); + // FlxG.log.add(ChartParser.parse()); + songSpeedType = ClientPrefs.getGameplaySetting('scrolltype','multiplicative'); + + switch(songSpeedType) + { + case "multiplicative": + songSpeed = SONG.speed * ClientPrefs.getGameplaySetting('scrollspeed', 1); + case "constant": + songSpeed = ClientPrefs.getGameplaySetting('scrollspeed', 1); + } + + Conductor.changeBPM(SONG.bpm); + + curSong = SONG.song; + + if (SONG.needsVoices && ClientPrefs.songLoading) + vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song)); + else + vocals = new FlxSound(); + + if (ClientPrefs.songLoading) vocals.pitch = playbackRate; + if (ClientPrefs.songLoading) FlxG.sound.list.add(vocals); + if (ClientPrefs.songLoading) FlxG.sound.list.add(new FlxSound().loadEmbedded(Paths.inst(PlayState.SONG.song))); + + notes = new FlxTypedGroup(); + add(notes); + notes.visible = ClientPrefs.showNotes; //that was easier than expected + + var noteData:Array = SONG.notes; + + var songName:String = Paths.formatToSongPath(SONG.song); + var file:String = Paths.json(songName + '/events'); + #if MODS_ALLOWED + if (FileSystem.exists(Paths.modsJson(songName + '/events')) || FileSystem.exists(file)) { + #else + if (OpenFlAssets.exists(file)) { + #end + var eventsData:Array = Song.loadFromJson('events', songName).events; + for (event in eventsData) //Event Notes + { + for (i in 0...event[1].length) + { + var newEventNote:Array = [event[0], event[1][i][0], event[1][i][1], event[1][i][2]]; + var subEvent:EventNote = { + strumTime: newEventNote[0] + ClientPrefs.noteOffset, + event: newEventNote[1], + value1: newEventNote[2], + value2: newEventNote[3] + }; + eventNotes.push(subEvent); + eventPushed(subEvent); + } + } + } + + for (section in noteData) + { + for (songNotes in section.sectionNotes) + { + var daStrumTime:Float = songNotes[0]; + var daNoteData:Int = 0; + if (!randomMode && !flip && !stairs && !waves) + { + daNoteData = Std.int(songNotes[1] % 4); + } + if (oneK) + { + daNoteData = 2; + } + if (randomMode) { + daNoteData = FlxG.random.int(0, 3); + } + if (flip) { + daNoteData = Std.int(Math.abs((songNotes[1] % 4) - 3)); + } + if (stairs && !waves) { + daNoteData = stair % 4; + stair++; + } + if (waves) { + switch (stair % 6) + { + case 0 | 1 | 2 | 3: + daNoteData = stair % 6; + case 4: + daNoteData = 2; + case 5: + daNoteData = 1; + } + stair++; + } + var gottaHitNote:Bool = section.mustHitSection; + + if (songNotes[1] > 3 && !opponentChart && !bothsides) + { + gottaHitNote = !section.mustHitSection; + } + if (songNotes[1] <= 3 && opponentChart && !bothsides) + { + gottaHitNote = !section.mustHitSection; + } + else if (!gottaHitNote && bothsides) + { + gottaHitNote = true; + } + + if (!gottaHitNote && !bothsides && ClientPrefs.mobileMidScroll) + { + songNotes[3] = 'Behind Note'; + } + if (gottaHitNote && !songNotes.hitCausesMiss) + { + totalNotes += 1; + } + if (!gottaHitNote) + { + opponentNoteTotal += 1; + } + + var oldNote:Note = unspawnNotes.length > 0 ? unspawnNotes[Std.int(unspawnNotes.length - 1)] : null; + + var swagNote:Note = new Note(daStrumTime, daNoteData, oldNote); + if (ClientPrefs.doubleGhost) + { + swagNote.row = Conductor.secsToRow(daStrumTime); + if(noteRows[gottaHitNote?0:1][swagNote.row]==null) + noteRows[gottaHitNote?0:1][swagNote.row]=[]; + noteRows[gottaHitNote ? 0 : 1][swagNote.row].push(swagNote); + } + swagNote.mustPress = gottaHitNote; + swagNote.sustainLength = songNotes[2]; + swagNote.gfNote = (section.gfSection && (songNotes[1]<4)); + swagNote.noteType = songNotes[3]; + if(!Std.isOfType(songNotes[3], String)) swagNote.noteType = editors.ChartingState.noteTypeList[songNotes[3]]; //Backward compatibility + compatibility with Week 7 charts + + swagNote.scrollFactor.set(); + unspawnNotes.push(swagNote); + + var floorSus:Int = Math.floor(swagNote.sustainLength / Conductor.stepCrochet); + if(floorSus > 0) { + for (susNote in 0...floorSus+1) + { + oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)]; + + var sustainNote:Note = new Note(daStrumTime + (Conductor.stepCrochet * susNote) + (Conductor.stepCrochet / FlxMath.roundDecimal(songSpeed, 2)), daNoteData, oldNote, true); + sustainNote.mustPress = gottaHitNote; + sustainNote.gfNote = (section.gfSection && (songNotes[1]<4)); + sustainNote.noteType = swagNote.noteType; + sustainNote.scrollFactor.set(); + swagNote.tail.push(sustainNote); + sustainNote.parent = swagNote; + unspawnNotes.push(sustainNote); + } + } + if(!noteTypeMap.exists(swagNote.noteType)) { + noteTypeMap.set(swagNote.noteType, true); + } + var jackNote:Note; + + if (jackingtime > 0) + { + for (i in 0...Std.int(jackingtime)) + { + jackNote = new Note(swagNote.strumTime + (15000/SONG.bpm) * (i + 1), swagNote.noteData, oldNote); + jackNote.scrollFactor.set(); + + jackNote.mustPress = swagNote.mustPress; + jackNote.sustainLength = swagNote.sustainLength; + jackNote.gfNote = swagNote.gfNote; + jackNote.noteType = swagNote.noteType; + if (ClientPrefs.doubleGhost) + { + jackNote.row = Conductor.secsToRow(daStrumTime); + if(noteRows[gottaHitNote?0:1][jackNote.row]==null) + noteRows[gottaHitNote?0:1][jackNote.row]=[]; + noteRows[gottaHitNote ? 0 : 1][jackNote.row].push(jackNote); + } + + unspawnNotes.push(jackNote); + + jackNote.mustPress = swagNote.mustPress; + + if (jackNote.mustPress) + { + jackNote.x += FlxG.width / 2; // general offset + totalNotes += 1; + } + if (!jackNote.mustPress) + { + opponentNoteTotal += 1; + } + if(!noteTypeMap.exists(jackNote.noteType)) { + noteTypeMap.set(jackNote.noteType, true); + } + } + } + } + sectionsLoaded += 1; + trace('loaded section ' + sectionsLoaded); + } + for (event in SONG.events) //Event Notes + { + for (i in 0...event[1].length) + { + var newEventNote:Array = [event[0], event[1][i][0], event[1][i][1], event[1][i][2]]; + var subEvent:EventNote = { + strumTime: newEventNote[0] + ClientPrefs.noteOffset, + event: newEventNote[1], + value1: newEventNote[2], + value2: newEventNote[3] + }; + eventNotes.push(subEvent); + eventPushed(subEvent); + } + } + + // trace(unspawnNotes.length); + // playerCounter += 1; + + var endTime = Sys.time(); + + var elapsedTime = endTime - startTime; + unspawnNotes.sort(sortByTime); + unspawnNotesCopy = unspawnNotes.copy(); + generatedMusic = true; + maxScore = totalNotes * (ClientPrefs.noMarvJudge ? 350 : 500); + var elapsedTime = endTime - startTime; + trace("Loaded chart in " + elapsedTime + " seconds"); + } + function eventPushed(event:EventNote) { + switch(event.event) { + case 'Change Character': + var charType:Int = 0; + switch(event.value1.toLowerCase()) { + case 'gf' | 'girlfriend' | '1': + charType = 2; + case 'dad' | 'opponent' | '0': + charType = 1; + default: + charType = Std.parseInt(event.value1); + if(Math.isNaN(charType)) charType = 0; + } + + var newCharacter:String = event.value2; + addCharacterToList(newCharacter, charType); + + case 'Dadbattle Spotlight': + dadbattleBlack = new BGSprite(null, -800, -400, 0, 0); + dadbattleBlack.makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK); + dadbattleBlack.alpha = 0.25; + dadbattleBlack.visible = false; + add(dadbattleBlack); + + dadbattleLight = new BGSprite('spotlight', 400, -400); + dadbattleLight.alpha = 0.375; + dadbattleLight.blend = ADD; + dadbattleLight.visible = false; + + dadbattleSmokes.alpha = 0.7; + dadbattleSmokes.blend = ADD; + dadbattleSmokes.visible = false; + add(dadbattleLight); + add(dadbattleSmokes); + + var offsetX = 200; + var smoke:BGSprite = new BGSprite('smoke', -1550 + offsetX, 660 + FlxG.random.float(-20, 20), 1.2, 1.05); + smoke.setGraphicSize(Std.int(smoke.width * FlxG.random.float(1.1, 1.22))); + smoke.updateHitbox(); + smoke.velocity.x = FlxG.random.float(15, 22); + smoke.active = true; + dadbattleSmokes.add(smoke); + var smoke:BGSprite = new BGSprite('smoke', 1550 + offsetX, 660 + FlxG.random.float(-20, 20), 1.2, 1.05); + smoke.setGraphicSize(Std.int(smoke.width * FlxG.random.float(1.1, 1.22))); + smoke.updateHitbox(); + smoke.velocity.x = FlxG.random.float(-15, -22); + smoke.active = true; + smoke.flipX = true; + dadbattleSmokes.add(smoke); + + + case 'Philly Glow': + blammedLightsBlack = new FlxSprite(FlxG.width * -0.5, FlxG.height * -0.5).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK); + blammedLightsBlack.visible = false; + insert(members.indexOf(phillyStreet), blammedLightsBlack); + + phillyWindowEvent = new BGSprite('philly/window', phillyWindow.x, phillyWindow.y, 0.3, 0.3); + phillyWindowEvent.setGraphicSize(Std.int(phillyWindowEvent.width * 0.85)); + phillyWindowEvent.updateHitbox(); + phillyWindowEvent.visible = false; + insert(members.indexOf(blammedLightsBlack) + 1, phillyWindowEvent); + + + phillyGlowGradient = new PhillyGlow.PhillyGlowGradient(-400, 225); //This shit was refusing to properly load FlxGradient so fuck it + phillyGlowGradient.visible = false; + insert(members.indexOf(blammedLightsBlack) + 1, phillyGlowGradient); + if(!ClientPrefs.flashing) phillyGlowGradient.intendedAlpha = 0.7; + + precacheList.set('philly/particle', 'image'); //precache particle image + phillyGlowParticles = new FlxTypedGroup(); + phillyGlowParticles.visible = false; + insert(members.indexOf(phillyGlowGradient) + 1, phillyGlowParticles); + } + + if(!eventPushedMap.exists(event.event) && SONG.song.toLowerCase() != 'anti-cheat-song') { + eventPushedMap.set(event.event, true); + } + } + + function eventNoteEarlyTrigger(event:EventNote):Float { + var returnedValue:Null = callOnLuas('eventEarlyTrigger', [event.event, event.value1, event.value2, event.strumTime], [], [0]); + if(returnedValue != null && returnedValue != 0 && returnedValue != FunkinLua.Function_Continue) { + return returnedValue; + } + + switch(event.event) { + case 'Kill Henchmen': //Better timing so that the kill sound matches the beat intended + return 280; //Plays 280ms before the actual position + } + return 0; + } + + function sortByTime(Obj1:Dynamic, Obj2:Dynamic):Int + { + return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime); + } + + function sortByShit(Obj1:Note, Obj2:Note):Int { + return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime); + } + + public var skipArrowStartTween:Bool = false; //for lua + private function generateStaticArrows(player:Int):Void + { + for (i in 0...4) + { + // FlxG.log.add(i); + var targetAlpha:Float = 1; + if (player < 1) + { + if(!ClientPrefs.opponentStrums) targetAlpha = 0; + else if(ClientPrefs.middleScroll || ClientPrefs.mobileMidScroll) targetAlpha = ClientPrefs.oppNoteAlpha; + if (ClientPrefs.mobileMidScroll) opponentStrums.members[i].x == FlxG.width - 2; //make it so that you're unable to see the opponent's strums if you have mobile styled middlescroll on + } + + var babyArrow:StrumNote = new StrumNote(ClientPrefs.middleScroll || ClientPrefs.mobileMidScroll ? STRUM_X_MIDDLESCROLL : STRUM_X, strumLine.y, i, player); + babyArrow.downScroll = ClientPrefs.downScroll; + if (!isStoryMode && !skipArrowStartTween) + { + //babyArrow.y -= 10; + babyArrow.alpha = 0; + FlxTween.tween(babyArrow, {/*y: babyArrow.y + 10,*/ alpha: targetAlpha}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * i)}); + } + else + { + babyArrow.alpha = targetAlpha; + } + + if (player == 1) + { + if (!opponentChart || opponentChart && ClientPrefs.middleScroll || opponentChart && ClientPrefs.mobileMidScroll || !opponentChart && ClientPrefs.mobileMidScroll) playerStrums.add(babyArrow); + else if (ClientPrefs.mobileMidScroll) insert(members.indexOf(playerStrums), babyArrow); + else opponentStrums.add(babyArrow); + } + else + { + if(ClientPrefs.middleScroll) + { + babyArrow.x += 310; + if(i > 1) { //Up and Right + babyArrow.x += FlxG.width / 2 + 25; + } + } + if(ClientPrefs.mobileMidScroll) + { + babyArrow.x += FlxG.width / 2; + } + if (!opponentChart || opponentChart && ClientPrefs.mobileMidScroll || opponentChart && ClientPrefs.mobileMidScroll || !opponentChart && ClientPrefs.mobileMidScroll) opponentStrums.add(babyArrow); + else if (ClientPrefs.mobileMidScroll) insert(members.indexOf(playerStrums), babyArrow); + else playerStrums.add(babyArrow); + } + + strumLineNotes.add(babyArrow); + babyArrow.postAddedToGroup(); + } + } + + override function openSubState(SubState:FlxSubState) + { + if (paused) + { + if (FlxG.sound.music != null) + { + if (ClientPrefs.songLoading) { + FlxG.sound.music.pause(); + vocals.pause(); + } + } + + if (startTimer != null && !startTimer.finished) + startTimer.active = false; + if (finishTimer != null && !finishTimer.finished) + finishTimer.active = false; + if (songSpeedTween != null) + songSpeedTween.active = false; + + if(carTimer != null) carTimer.active = false; + + var chars:Array = [boyfriend, gf, dad]; + for (char in chars) { + if(char != null && char.colorTween != null) { + char.colorTween.active = false; + } + } + + for (tween in modchartTweens) { + tween.active = false; + } + for (timer in modchartTimers) { + timer.active = false; + } + } + + super.openSubState(SubState); + } + + override function closeSubState() + { + if (paused) + { + if (FlxG.sound.music != null && !startingSong && !ClientPrefs.noSyncing) + { + resyncVocals(); + } + + if (startTimer != null && !startTimer.finished) + startTimer.active = true; + if (finishTimer != null && !finishTimer.finished) + finishTimer.active = true; + if (songSpeedTween != null) + songSpeedTween.active = true; + + if(carTimer != null) carTimer.active = true; + + var chars:Array = [boyfriend, gf, dad]; + for (char in chars) { + if(char != null && char.colorTween != null) { + char.colorTween.active = true; + } + } + + for (tween in modchartTweens) { + tween.active = true; + } + for (timer in modchartTimers) { + timer.active = true; + } + paused = false; + callOnLuas('onResume', []); + + #if desktop + if (startTimer != null && startTimer.finished) + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter(), true, songLength - Conductor.songPosition - ClientPrefs.noteOffset); + } + else + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); + } + #end + } + + super.closeSubState(); + } + + override public function onFocus():Void + { + #if desktop + if (health > 0 && !paused) + { + if (Conductor.songPosition > 0.0) + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter(), true, songLength - Conductor.songPosition - ClientPrefs.noteOffset); + } + else + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); + } + } + #end + + super.onFocus(); + } + + override public function onFocusLost():Void + { + #if desktop + if (health > 0 && !paused) + { + DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); + } + #end + + super.onFocusLost(); + } + + function resyncVocals():Void + { + if(finishTimer != null) return; + + FlxG.sound.music.pitch = playbackRate; + vocals.pitch = playbackRate; + if (ClientPrefs.resyncType == 'Leather') + { + if(!(Conductor.songPosition > 20 && FlxG.sound.music.time < 20)) + { + //trace("SONG POS: " + Conductor.songPosition + " | Musice: " + FlxG.sound.music.time + " / " + FlxG.sound.music.length); + + vocals.pause(); + FlxG.sound.music.pause(); + + if(FlxG.sound.music.time >= FlxG.sound.music.length) + Conductor.songPosition = FlxG.sound.music.length; + else + Conductor.songPosition = FlxG.sound.music.time; + + vocals.time = Conductor.songPosition; + + FlxG.sound.music.play(); + vocals.play(); + } + else + { + while(Conductor.songPosition > 20 && FlxG.sound.music.time < 20) + { + trace("SONG POS: " + Conductor.songPosition + " | Music Pos: " + FlxG.sound.music.time + " / " + FlxG.sound.music.length); + + FlxG.sound.music.time = Conductor.songPosition; + vocals.time = Conductor.songPosition; + + FlxG.sound.music.play(); + vocals.play(); + } + } + } + else if (ClientPrefs.resyncType == 'Psych') + { + vocals.pause(); + FlxG.sound.music.play(); + + Conductor.songPosition = FlxG.sound.music.time; + if (Conductor.songPosition <= vocals.length) + { + vocals.time = Conductor.songPosition; + } + vocals.play(); + } + } + + public var paused:Bool = false; + public var canReset:Bool = true; + var startedCountdown:Bool = false; + var canPause:Bool = true; + var limoSpeed:Float = 0; + var pbRM:Float = 2.0; + override public function update(elapsed:Float) + { + if (health <= 0 && practiceMode && ClientPrefs.zeroHealthLimit) + { + health = 0; //set health to 0 if on practice mode and you get to 0% + } + if (combo >= 1.79e+308) combo = 1.79e+308; //Combo exceeded the maximum value that a Float can go up to, lock it at 1.79e+308 to avoid a reset to 0 + if (totalNotesPlayed >= 1.79e+308) totalNotesPlayed = 1.79e+308; //Note hit count exceeded the maximum value that a Float can go up to, lock it at 1.79e+308 to avoid a reset to 0 + if (enemyHits >= 1.79e+308) enemyHits = 1.79e+308; //Opponent's note hit count exceeded the maximum value that a Float can go up to, lock it at 1.79e+308 to avoid a reset to 0 + if (FlxG.sound.music.length - Conductor.songPosition <= 1000 && ClientPrefs.communityGameBot && cpuControlled) { + ratingName = 'you used the community game bot option LMFAOOO'; + ratingFC = 'skill issue'; + } + if (ClientPrefs.comboScoreEffect && ClientPrefs.comboMultiType == 'osu!') comboMultiplier = 1 + FlxMath.roundDecimal((combo / 100), 2); + if (ClientPrefs.comboScoreEffect && comboMultiplier > ClientPrefs.comboMultLimit) comboMultiplier = ClientPrefs.comboMultLimit; + /*if (FlxG.keys.justPressed.NINE) + { + iconP1.swapOldIcon(); + }*/ + if (ClientPrefs.pbRControls) + { + if (FlxG.keys.pressed.SHIFT) { + pbRM = 4.0; + } else { + pbRM = 2.0; + } + if (FlxG.keys.justPressed.SLASH) { + playbackRate /= pbRM; + } + if (FlxG.keys.justPressed.PERIOD) { + playbackRate *= pbRM; + } + } + healthBar.setRange(0, maxHealth); + + callOnLuas('onUpdate', [elapsed]); + + playbackRateDecimal = FlxMath.roundDecimal(playbackRate, 2); + + if (goods > 0 || bads > 0 || shits > 0 || songMisses > 0 && sickOnly) + { + // if it isn't a sick, and sick only mode is on YOU DIE + if (sickOnly) + { + health = -2; + } + } + + if (tankmanAscend) + { + if (curStep > 895 && curStep < 1151) + { + camGame.zoom = 0.8; + } + } + + switch (curStage) + { + case 'tank': + moveTank(elapsed); + case 'schoolEvil': + if(!ClientPrefs.lowQuality && bgGhouls.animation.curAnim.finished) { + bgGhouls.visible = false; + } + case 'philly': + if (trainMoving) + { + trainFrameTiming += elapsed; + + if (trainFrameTiming >= 1 / 24) + { + updateTrainPos(); + trainFrameTiming = 0; + } + } + phillyWindow.alpha -= (Conductor.crochet / 1000) * FlxG.elapsed * 1.5; + + if(phillyGlowParticles != null) + { + var i:Int = phillyGlowParticles.members.length-1; + while (i > 0) + { + var particle = phillyGlowParticles.members[i]; + if(particle.alpha < 0) + { + particle.kill(); + phillyGlowParticles.remove(particle, true); + particle.destroy(); + } + --i; + } + } + case 'limo': + if(!ClientPrefs.lowQuality) { + grpLimoParticles.forEach(function(spr:BGSprite) { + if(spr.animation.curAnim.finished) { + spr.kill(); + grpLimoParticles.remove(spr, true); + spr.destroy(); + } + }); + + switch(limoKillingState) { + case 1: + limoMetalPole.x += 5000 * elapsed; + limoLight.x = limoMetalPole.x - 180; + limoCorpse.x = limoLight.x - 50; + limoCorpseTwo.x = limoLight.x + 35; + + var dancers:Array = grpLimoDancers.members; + for (i in 0...dancers.length) { + if(dancers[i].x < FlxG.width * 1.5 && limoLight.x > (370 * i) + 170) { + switch(i) { + case 0 | 3: + if(i == 0) FlxG.sound.play(Paths.sound('dancerdeath'), 0.5); + + var diffStr:String = i == 3 ? ' 2 ' : ' '; + var particle:BGSprite = new BGSprite('gore/noooooo', dancers[i].x + 200, dancers[i].y, 0.4, 0.4, ['hench leg spin' + diffStr + 'PINK'], false); + grpLimoParticles.add(particle); + var particle:BGSprite = new BGSprite('gore/noooooo', dancers[i].x + 160, dancers[i].y + 200, 0.4, 0.4, ['hench arm spin' + diffStr + 'PINK'], false); + grpLimoParticles.add(particle); + var particle:BGSprite = new BGSprite('gore/noooooo', dancers[i].x, dancers[i].y + 50, 0.4, 0.4, ['hench head spin' + diffStr + 'PINK'], false); + grpLimoParticles.add(particle); + + var particle:BGSprite = new BGSprite('gore/stupidBlood', dancers[i].x - 110, dancers[i].y + 20, 0.4, 0.4, ['blood'], false); + particle.flipX = true; + particle.angle = -57.5; + grpLimoParticles.add(particle); + case 1: + limoCorpse.visible = true; + case 2: + limoCorpseTwo.visible = true; + } //Note: Nobody cares about the fifth dancer because he is mostly hidden offscreen :( + dancers[i].x += FlxG.width * 2; + } + } + + if(limoMetalPole.x > FlxG.width * 2) { + resetLimoKill(); + limoSpeed = 800; + limoKillingState = 2; + } + + case 2: + limoSpeed -= 4000 * elapsed; + bgLimo.x -= limoSpeed * elapsed; + if(bgLimo.x > FlxG.width * 1.5) { + limoSpeed = 3000; + limoKillingState = 3; + } + + case 3: + limoSpeed -= 2000 * elapsed; + if(limoSpeed < 1000) limoSpeed = 1000; + + bgLimo.x -= limoSpeed * elapsed; + if(bgLimo.x < -275) { + limoKillingState = 4; + limoSpeed = 800; + } + + case 4: + bgLimo.x = FlxMath.lerp(bgLimo.x, -150, CoolUtil.boundTo(elapsed * 9, 0, 1)); + if(Math.round(bgLimo.x) == -150) { + bgLimo.x = -150; + limoKillingState = 0; + } + } + + if(limoKillingState > 2) { + var dancers:Array = grpLimoDancers.members; + for (i in 0...dancers.length) { + dancers[i].x = (370 * i) + bgLimo.x + 280; + } + } + } + case 'mall': + if(heyTimer > 0) { + heyTimer -= elapsed; + if(heyTimer <= 0) { + bottomBoppers.dance(true); + heyTimer = 0; + } + } + } + + if(!inCutscene) { + var lerpVal:Float = CoolUtil.boundTo(elapsed * 2.4 * cameraSpeed * playbackRate, 0, 1); + camFollowPos.setPosition(FlxMath.lerp(camFollowPos.x + moveCamTo[0]/102, camFollow.x + moveCamTo[0]/102, lerpVal), FlxMath.lerp(camFollowPos.y + moveCamTo[1]/102, camFollow.y + moveCamTo[1]/102, lerpVal)); + if (ClientPrefs.charsAndBG) { + if(!startingSong && !endingSong && boyfriend.animation.curAnim != null && boyfriend.animation.curAnim.name.startsWith('idle')) { + boyfriendIdleTime += elapsed; + if(boyfriendIdleTime >= 0.15) { // Kind of a mercy thing for making the achievement easier to get as it's apparently frustrating to some playerss + boyfriendIdled = true; + } + } else { + boyfriendIdleTime = 0; + } + } + var panLerpVal:Float = CoolUtil.clamp(elapsed * 4.4 * cameraSpeed, 0, 1); + moveCamTo[0] = FlxMath.lerp(moveCamTo[0], 0, panLerpVal); + moveCamTo[1] = FlxMath.lerp(moveCamTo[1], 0, panLerpVal); + } + + if (ClientPrefs.hudType == 'Leather Engine' && SONG.notes[curSection] != null) timeBar.color = SONG.notes[curSection].mustHitSection ? FlxColor.fromRGB(boyfriend.healthColorArray[0], boyfriend.healthColorArray[1], boyfriend.healthColorArray[2]) : FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2]); +if (ClientPrefs.showNPS) { + var currentTime = Date.now().getTime(); + var timeThreshold = ClientPrefs.npsWithSpeed ? 1000 / playbackRate : 1000; + + // Track the count of items to remove for notesHitDateArray + var notesToRemoveCount:Int = 0; + + // Filter notesHitDateArray and notesHitArray in place + for (i in 0...notesHitDateArray.length) { + var cock:Date = notesHitDateArray[i]; + if (cock != null && (cock.getTime() + timeThreshold < currentTime)) { + notesToRemoveCount++; + } + } + + // Remove items from notesHitDateArray and notesHitArray if needed + if (notesToRemoveCount > 0) { + notesHitDateArray.splice(0, notesToRemoveCount); + notesHitArray.splice(0, notesToRemoveCount); + if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0 && judgementCounter != null) updateRatingCounter(); + if (!ClientPrefs.hideScore && scoreTxtUpdateFrame == 0 && scoreTxt != null) updateScore(); + if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); + } + + // Calculate sum of NPS values + var sum:Float = 0.0; + for (value in notesHitArray) { + sum += value; + } + nps = sum; + + // Similar tracking and filtering logic for oppNotesHitDateArray + var oppNotesToRemoveCount:Int = 0; + + for (i in 0...oppNotesHitDateArray.length) { + var cock:Date = oppNotesHitDateArray[i]; + if (cock != null && (cock.getTime() + timeThreshold < currentTime)) { + oppNotesToRemoveCount++; + } + } + + // Remove items from oppNotesHitDateArray and oppNotesHitArray if needed + if (oppNotesToRemoveCount > 0) { + oppNotesHitDateArray.splice(0, oppNotesToRemoveCount); + oppNotesHitArray.splice(0, oppNotesToRemoveCount); + if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0 && judgementCounter != null) updateRatingCounter(); + if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); + } + + // Calculate sum of NPS values for the opponent + var oppSum:Float = 0.0; + for (value in oppNotesHitArray) { + oppSum += value; + } + oppNPS = oppSum; + + // Update maxNPS and maxOppNPS if needed + if (oppNPS > maxOppNPS) { + maxOppNPS = oppNPS; + } + if (nps > maxNPS) { + maxNPS = nps; + } +} + + if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) { + hitTxt.text = 'Notes Hit: ' + FlxStringUtil.formatMoney(totalNotesPlayed, false) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + + '\nNPS (Max): ' + FlxStringUtil.formatMoney(nps, false) + ' (' + FlxStringUtil.formatMoney(maxNPS, false) + ')' + + '\nOpponent Notes Hit: ' + FlxStringUtil.formatMoney(enemyHits, false) + + '\nOpponent NPS (Max): ' + FlxStringUtil.formatMoney(oppNPS, false) + ' (' + FlxStringUtil.formatMoney(maxOppNPS, false) + ')' + + '\nTotal Note Hits: ' + FlxStringUtil.formatMoney(Math.abs(totalNotesPlayed + enemyHits), false) + + '\nVideo Speedup: ' + Math.abs(playbackRate / playbackRate / playbackRate) + 'x'; + } + if (notesHitArray.length == 1 || oppNotesHitArray.length == 1) { + if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0 && judgementCounter != null) updateRatingCounter(); + if (!ClientPrefs.hideScore && scoreTxtUpdateFrame == 0 && scoreTxt != null) updateScore(); + if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); + } + + if (combo > maxCombo) + maxCombo = combo; + + super.update(elapsed); + judgeCountUpdateFrame = 0; + compactUpdateFrame = 0; + scoreTxtUpdateFrame = 0; + + if (shownScore != songScore && ClientPrefs.hudType == 'JS Engine' && Math.abs(shownScore - songScore) >= 10) { + shownScore = FlxMath.lerp(shownScore, songScore, 0.4 / (ClientPrefs.framerate / 60)); + lerpingScore = true; // Indicate that lerping is in progress + } else { + shownScore = songScore; + lerpingScore = false; + } + + if (lerpingScore) updateScore(); + + if (ClientPrefs.smoothHealth && ClientPrefs.smoothHealthType == 'Indie Cross') + { + if (ClientPrefs.framerate > 60) + { + displayedHealth = FlxMath.lerp(displayedHealth, health, .1); + } else if (ClientPrefs.framerate == 60) + { + displayedHealth = FlxMath.lerp(displayedHealth, health, .4); + } + } + if (ClientPrefs.smoothHealth && ClientPrefs.smoothHealthType == 'Golden Apple 1.5') + { + displayedHealth = FlxMath.lerp(displayedHealth, health, CoolUtil.boundTo(elapsed * 20, 0, 1)); + } + if (!ClientPrefs.smoothHealth) //so basically don't make the health smooth if you have that off + { + displayedHealth = health; + } + + setOnLuas('curDecStep', curDecStep); + setOnLuas('curDecBeat', curDecBeat); + + if(botplayTxt != null && ClientPrefs.hudType != "Mic'd Up" && ClientPrefs.hudType != 'Kade Engine' && ClientPrefs.botTxtFade) { + botplaySine += 180 * elapsed; + botplayTxt.alpha = 1 - Math.sin((Math.PI * botplaySine) / 180 * playbackRate); + } + if((botplayTxt != null && cpuControlled && !ClientPrefs.showcaseMode) && ClientPrefs.randomBotplayText && !ClientPrefs.communityGameBot) { + if(botplayTxt.text == "this text is gonna kick you out of botplay in 10 seconds" && !botplayUsed || botplayTxt.text == "Your Botplay Free Trial will end in 10 seconds." && !botplayUsed) + { + botplayUsed = true; + new FlxTimer().start(10, function(tmr:FlxTimer) + { + cpuControlled = false; + botplayUsed = false; + botplayTxt.visible = false; + }); + } + if(botplayTxt.text == "You use botplay? In 10 seconds I knock your botplay thing and text so you'll never use it >:)" && !botplayUsed) + { + botplayUsed = true; + new FlxTimer().start(10, function(tmr:FlxTimer) + { + cpuControlled = false; + botplayUsed = false; + FlxG.sound.play(Paths.sound('pipe'), 10); + botplayTxt.visible = false; + PauseSubState.botplayLockout = true; + }); + } + if(botplayTxt.text == "you have 10 seconds to run." && !botplayUsed) + { + botplayUsed = true; + new FlxTimer().start(10, function(tmr:FlxTimer) + { + var vidSpr:FlxSprite; + var videoDone:Bool = true; + var video:MP4Handler = new MP4Handler(); // it plays but it doesn't show??? + vidSpr = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.WHITE); + add(vidSpr); + #if (hxCodec < "3.0.0") + video.playVideo(Paths.video('scary'), false, false); + video.finishCallback = function() + { + videoDone = true; + vidSpr.visible = false; + Sys.exit(0); + }; + #else + video.play(Paths.video('scary')); + video.onEndReached.add(function(){ + video.dispose(); + videoDone = true; + vidSpr.visible = false; + Sys.exit(0); + }); + #end + }); + } + if(botplayTxt.text == "you're about to die in 30 seconds" && !botplayUsed) + { + botplayUsed = true; + new FlxTimer().start(30, function(tmr:FlxTimer) + { + health = 0; + }); + } + if(botplayTxt.text == "3 minutes until Boyfriend steals your liver." && !botplayUsed) + { + var title:String = 'Incoming Alert from Boyfriend'; + var message:String = '3 minutes until Boyfriend steals your liver!'; + FlxG.sound.music.pause(); + vocals.pause(); + + lime.app.Application.current.window.alert(message, title); + FlxG.sound.music.resume(); + vocals.resume(); + botplayUsed = true; + new FlxTimer().start(180, function(tmr:FlxTimer) + { + Sys.exit(0); + }); + } + if(botplayTxt.text == "3 minutes until I steal your liver." && !botplayUsed) + { + var title:String = 'Incoming Alert from Jordan'; + var message:String = '3 minutes until I steal your liver.'; + FlxG.sound.music.pause(); + vocals.pause(); + + lime.app.Application.current.window.alert(message, title); + FlxG.sound.music.resume(); + vocals.resume(); + botplayUsed = true; + new FlxTimer().start(180, function(tmr:FlxTimer) + { + Sys.exit(0); + }); + } + } + + if ((controls.PAUSE #if android || FlxG.android.justReleased.BACK #end) && startedCountdown && canPause && !softlocked) + { + if (!ClientPrefs.noPausing) { + var ret:Dynamic = callOnLuas('onPause', [], false); + if(ret != FunkinLua.Function_Stop) { + openPauseMenu(); + } + } + else if (ClientPrefs.noPausing) { + FlxTween.cancelTweensOf(pauseWarnText); + trace("Player has attempted to pause the song, but 'Force Disable Pausing' is enabled! (Tries: " + tries + ")"); + pauseWarnText.visible = true; + pauseWarnText.alpha = 1; + FlxG.sound.play(Paths.sound('tried'), 1); + tries++; + insert(members.indexOf(strumLineNotes), pauseWarnText); + FlxTween.tween(pauseWarnText, {alpha: 0}, 1 / playbackRate, { + startDelay: 2 / playbackRate, + onComplete: _ -> { + tries = 0; + pauseWarnText.visible = false; + } + }); + switch (tries) + { + case 1, 2, 3, 4, 5, 6, 7, 8, 9: + pauseWarnText.text = "Pausing is disabled! Turn it back on in Settings -> Gameplay -> 'Force Disable Pausing'"; + case 10, 11, 12, 13, 14, 15, 16, 17, 18, 19: + pauseWarnText.text = "OK we get it, the sound's funny, now stop pausing."; + case 20, 21, 22, 23, 24, 25, 26, 27, 28, 29: + pauseWarnText.text = "dude. stop."; + case 30, 31, 32, 33, 34: + pauseWarnText.text = "OK, if you continue, I'm softlocking the game."; + case 35, 36, 37, 38, 39: + pauseWarnText.text = "STOP."; + case 40: + pauseWarnText.text = "fuck off."; + FlxG.sound.play(Paths.sound('pipe'), 1); + if (ClientPrefs.songLoading) vocals.stop(); + if (ClientPrefs.songLoading) FlxG.sound.music.stop(); + Conductor.songPosition = -10000000000; + restartTimer = new FlxTimer().start(10, function(_) { + PauseSubState.restartSong(true); + }); + case 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59: + pauseWarnText.text = "stop trying to pause dumbass this is getting you nowhere"; + case 60: + pauseWarnText.text = "I CAN PERMANENTLY PAUSE FOR YOU, IF THAT'S WHAT YOU WANT."; + case 80: + pauseWarnText.text = "STOP. PAUSING."; + case 90: + pauseWarnText.text = "IM WARNING YOU, STOP PAUSING."; + case 95: + pauseWarnText.text = "I WILL NOT HESITATE TO SOFTLOCK THIS GAME RIGHT NOW."; + case 99: + pauseWarnText.text = "pause one more fucking time i FUCKING DARE YOU."; + case 100: + pauseWarnText.text = "ok fine you stupid fuck ive paused your fucking game, are you happy now"; + FlxG.sound.play(Paths.sound('loudvine'), 1); + if (restartTimer != null) restartTimer.cancel(); + softlocked = true; + trace("softlocked the game lmao"); + } + } + } + + if (FlxG.keys.anyJustPressed(debugKeysChart) && !endingSong && !inCutscene && !softlocked) + { + if (!ClientPrefs.antiCheatEnable) + { + openChartEditor(); + } + if (ClientPrefs.antiCheatEnable) + { + PlayState.SONG = Song.loadFromJson('Anti-cheat-song', 'Anti-cheat-song'); + LoadingState.loadAndSwitchState(new PlayState()); + } + } + + // FlxG.watch.addQuick('VOL', vocals.amplitudeLeft); + // FlxG.watch.addQuick('VOLRight', vocals.amplitudeRight); + + if (ClientPrefs.iconBounceType == 'Old Psych') { + iconP1.setGraphicSize(Std.int(FlxMath.lerp(150, iconP1.width, CoolUtil.boundTo(1 - (elapsed * 30 * playbackRate), 0, 1)))); + iconP2.setGraphicSize(Std.int(FlxMath.lerp(150, iconP2.width, CoolUtil.boundTo(1 - (elapsed * 30 * playbackRate), 0, 1)))); + } + if (ClientPrefs.iconBounceType == 'Strident Crisis') { + iconP1.setGraphicSize(Std.int(FlxMath.lerp(150, iconP1.width, 0.50 / playbackRate))); + iconP1.updateHitbox(); + + iconP2.setGraphicSize(Std.int(FlxMath.lerp(150, iconP2.width, 0.50 / playbackRate))); + iconP2.updateHitbox(); + } + if (ClientPrefs.iconBounceType == 'Dave and Bambi') { + iconP1.setGraphicSize(Std.int(FlxMath.lerp(150, iconP1.width, 0.8 / playbackRate)),Std.int(FlxMath.lerp(150, iconP1.height, 0.8 / playbackRate))); + iconP2.setGraphicSize(Std.int(FlxMath.lerp(150, iconP2.width, 0.8 / playbackRate)),Std.int(FlxMath.lerp(150, iconP2.height, 0.8 / playbackRate))); + } + if (ClientPrefs.iconBounceType == 'Plank Engine') { + var funnyBeat = (Conductor.songPosition / 1000) * (Conductor.bpm / 60); + + iconP1.offset.y = Math.abs(Math.sin(funnyBeat * Math.PI)) * 16 - 4; + iconP2.offset.y = Math.abs(Math.sin(funnyBeat * Math.PI)) * 16 - 4; + } + if (ClientPrefs.iconBounceType == 'New Psych') { + var mult:Float = FlxMath.lerp(1, iconP1.scale.x, CoolUtil.boundTo(1 - (elapsed * 9 * playbackRate), 0, 1)); + iconP1.scale.set(mult, mult); + iconP1.updateHitbox(); + + var mult:Float = FlxMath.lerp(1, iconP2.scale.x, CoolUtil.boundTo(1 - (elapsed * 9 * playbackRate), 0, 1)); + iconP2.scale.set(mult, mult); + iconP2.updateHitbox(); + } + if (ClientPrefs.iconBounceType == 'VS Steve') { + var mult:Float = FlxMath.lerp(1, iconP1.scale.x, CoolUtil.boundTo(1 - (elapsed * 9 * playbackRate), 0, 1)); + iconP1.scale.set(mult, mult); + iconP1.updateHitbox(); + + var mult:Float = FlxMath.lerp(1, iconP2.scale.x, CoolUtil.boundTo(1 - (elapsed * 9 * playbackRate), 0, 1)); + iconP2.scale.set(mult, mult); + iconP2.updateHitbox(); + } + + if (ClientPrefs.iconBounceType == 'Golden Apple') { + iconP1.centerOffsets(); + iconP2.centerOffsets(); + } + iconP1.updateHitbox(); + iconP2.updateHitbox(); + + var iconOffset:Int = 26; + + if (ClientPrefs.smoothHealth && ClientPrefs.smoothHealthType != 'Golden Apple 1.5' || !ClientPrefs.smoothHealth) //checks if you're using smooth health. if you are, but are not using the indie cross one then you know what that means + { + iconP1.x = (opponentChart ? -593 : 0) + healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, (opponentChart ? -100 : 100), 100, 0) * 0.01)) + (150 * iconP1.scale.x - 150) / 2 - iconOffset; + iconP2.x = (opponentChart ? -593 : 0) + healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, (opponentChart ? -100 : 100), 100, 0) * 0.01)) - (150 * iconP2.scale.x) / 2 - iconOffset * 2; + } + if (ClientPrefs.smoothHealth && ClientPrefs.smoothHealthType == 'Golden Apple 1.5') //really makes it feel like the gapple 1.5 build's health tween + { + var percent:Float = 1 - (opponentChart ? displayedHealth / maxHealth * -1 : displayedHealth / maxHealth); //checks if you're playing as the opponent. if so, uses the negative percent, otherwise uses the normal one + iconP1.x = (opponentChart ? -593 : 0) + healthBar.x + (healthBar.width * percent) + (150 * iconP1.scale.x - 150) / 2 - iconOffset; + iconP2.x = (opponentChart ? -593 : 0) + healthBar.x + (healthBar.width * percent) - (150 * iconP2.scale.x) / 2 - iconOffset * 2; + } + + if (generatedMusic) { + if (startedCountdown && canPause && !endingSong) { + if (playbackRate <= 256) endingTimeLimit = 20; + // Song ends abruptly on slow rate even with second condition being deleted, + // and if it's deleted on songs like cocoa then it would end without finishing instrumental fully, + // so no reason to delete it at all + if (ClientPrefs.songLoading && FlxG.sound.music.length - Conductor.songPosition <= endingTimeLimit && trollingMode) { //stop crashes when playing normally + if (ClientPrefs.trollMaxSpeed == 'Highest') loopSongHighest(); + if (ClientPrefs.trollMaxSpeed == 'High') loopSongHigh(); + if (ClientPrefs.trollMaxSpeed == 'Medium') loopSongMedium(); + if (ClientPrefs.trollMaxSpeed == 'Low') loopSongLow(); + if (ClientPrefs.trollMaxSpeed == 'Lower') loopSongLower(); + if (ClientPrefs.trollMaxSpeed == 'Lowest') loopSongLowest(); + if (ClientPrefs.trollMaxSpeed == 'Disabled') loopSongNoLimit(); + FlxG.sound.music.time = 0; + vocals.time = 0; + Conductor.songPosition = 0; + curSection = 0; + curBeat = 0; + curStep = 0; + } + if (ClientPrefs.songLoading && FlxG.sound.music.length - Conductor.songPosition <= endingTimeLimit && SONG.song.toLowerCase() == 'anti-cheat-song') { //stop crashes when playing normally + infiniteLoop(); + FlxG.sound.music.time = 0; + vocals.time = 0; + Conductor.songPosition = 0; + curSection = 0; + curBeat = 0; + curStep = 0; + } + } + } + + if (28820000 - Conductor.songPosition <= 20 && SONG.song.toLowerCase() == 'desert bus') { //stop crashes when playing normally + endSong(); + } + + if (health > maxHealth) + health = maxHealth; + + if ((opponentChart ? iconP2 : iconP1).animation.frames == 3) { + if (healthBar.percent < 20) + (opponentChart ? iconP2 : iconP1).animation.curAnim.curFrame = 1; + else if (healthBar.percent >80) + (opponentChart ? iconP2 : iconP1).animation.curAnim.curFrame = 2; + else + (opponentChart ? iconP2 : iconP1).animation.curAnim.curFrame = 0; + } + else { + if (healthBar.percent < 20) + (opponentChart ? iconP2 : iconP1).animation.curAnim.curFrame = 1; + else + (opponentChart ? iconP2 : iconP1).animation.curAnim.curFrame = 0; + } + if ((opponentChart ? iconP1 : iconP2).animation.frames == 3) { + if (healthBar.percent > 80) + (opponentChart ? iconP1 : iconP2).animation.curAnim.curFrame = 1; + else if (healthBar.percent < 20) + (opponentChart ? iconP1 : iconP2).animation.curAnim.curFrame = 2; + else + (opponentChart ? iconP1 : iconP2).animation.curAnim.curFrame = 0; + } else { + if (healthBar.percent > 80) + (opponentChart ? iconP1 : iconP2).animation.curAnim.curFrame = 1; + else + (opponentChart ? iconP1 : iconP2).animation.curAnim.curFrame = 0; + } + + if (FlxG.keys.anyJustPressed(debugKeysCharacter) && !endingSong && !inCutscene && !softlocked) { + persistentUpdate = false; + paused = true; + cancelMusicFadeTween(); + MusicBeatState.switchState(new CharacterEditorState(SONG.player2)); + } + + if (startedCountdown) + { + Conductor.songPosition += FlxG.elapsed * 1000 * playbackRate; + } + + if (startingSong) + { + if (startedCountdown && Conductor.songPosition >= 0) + startSong(); + else if(!startedCountdown) + Conductor.songPosition = -Conductor.crochet * 5; + } + else + { + if (!paused) + { + songTime += FlxG.game.ticks - previousFrameTime; + previousFrameTime = FlxG.game.ticks; + //Interpolation type beat + if (Conductor.lastSongPos != Conductor.songPosition && ClientPrefs.songLoading) + { + songTime = (songTime + Conductor.songPosition) / 2; + Conductor.lastSongPos = Conductor.songPosition; + // Conductor.songPosition += FlxG.elapsed * 1000; + // trace('MISSED FRAME'); + } + + if(updateTime) { + var curTime:Float = Conductor.songPosition - ClientPrefs.noteOffset; + if(curTime < 0) curTime = 0; + songPercent = (curTime / songLength); + var songDurationSeconds:Float = FlxMath.roundDecimal(songLength / 1000, 0); + songPercentThing = FlxMath.roundDecimal(curTime / songLength * 100, ClientPrefs.percentDecimals); + playbackRateDecimal = FlxMath.roundDecimal(playbackRate, 2); + + var songCalc:Float = (songLength - curTime); + if(ClientPrefs.timeBarType == 'Time Elapsed' || ClientPrefs.timeBarType == 'Modern Time' || ClientPrefs.timeBarType == 'Song Name + Time') songCalc = curTime; + + var secondsTotal:Int = 0; + + secondsTotal = Math.floor(songCalc / 1000); + if(secondsTotal < 0) secondsTotal = 0; + if(trollingMode && ClientPrefs.songLoading && Conductor.songPosition - FlxG.sound.music.length == endingTimeLimit) secondsTotal == secondsTotal + FlxG.sound.music.length; + + + var hoursRemaining:Int = Math.floor(secondsTotal / 3600); + var minutesRemaining:Int = Math.floor(secondsTotal / 60) % 60; + var minutesRemainingShit:String = '' + minutesRemaining; + var secondsRemaining:String = '' + secondsTotal % 60; + + if(secondsRemaining.length < 2) secondsRemaining = '0' + secondsRemaining; //let's see if the old time format works actually + //if (minutesRemaining == 60) minutesRemaining = 0; //reset the minutes to 0 every time it counts another hour + if (minutesRemainingShit.length < 2) minutesRemainingShit = '0' + minutesRemaining; + //also, i wont add a day thing because there's no way someone can mod a song that's over 24 hours long into this engine + + var hoursShown:Int = Math.floor(songDurationSeconds / 3600); + var minutesShown:Int = Math.floor(songDurationSeconds / 60) % 60; + var minutesShownShit:String = '' + minutesShown; + var secondsShown:String = '' + songDurationSeconds % 60; + if(secondsShown.length < 2) secondsShown = '0' + secondsShown; //let's see if the old time format works actually + if (minutesShownShit.length < 2) minutesShownShit = '0' + minutesShown; + + + if(ClientPrefs.timeBarType != 'Song Name' && songLength <= 3600000) + timeTxt.text = FlxStringUtil.formatTime(secondsTotal, false); + + if(ClientPrefs.timeBarType != 'Song Name' && songLength >= 3600000) + timeTxt.text = hoursRemaining + ':' + minutesRemainingShit + ':' + secondsRemaining; + + if(ClientPrefs.timeBarType == 'Modern Time' && songLength <= 3600000) + timeTxt.text = FlxStringUtil.formatTime(secondsTotal, false) + ' / ' + FlxStringUtil.formatTime(songLength / 1000, false); + + if(ClientPrefs.timeBarType == 'Modern Time' && songLength >= 3600000) + timeTxt.text = hoursRemaining + ':' + minutesRemainingShit + ':' + secondsRemaining + ' / ' + hoursShown + ':' + minutesShownShit + ':' + secondsShown; + + if(ClientPrefs.timeBarType == 'Song Name + Time' && songLength <= 3600000) + timeTxt.text = SONG.song + ' (' + FlxStringUtil.formatTime(secondsTotal, false) + ' / ' + FlxStringUtil.formatTime(songLength / 1000, false) + ')'; + + if(ClientPrefs.timeBarType == 'Song Name + Time' && songLength >= 3600000) + timeTxt.text = SONG.song + ' (' + hoursRemaining + ':' + minutesRemainingShit + ':' + secondsRemaining + ' / ' + hoursShown + ':' + minutesShownShit + ':' + secondsShown + ')'; + + if(ClientPrefs.timebarShowSpeed && ClientPrefs.timeBarType != 'Song Name') timeTxt.text += ' (' + playbackRateDecimal + 'x)'; + if(ClientPrefs.timebarShowSpeed && ClientPrefs.timeBarType == 'Song Name') timeTxt.text = SONG.song + ' (' + playbackRateDecimal + 'x)'; + if (cpuControlled && ClientPrefs.timeBarType != 'Song Name' && !ClientPrefs.communityGameBot) timeTxt.text += ' (Bot)'; + if(ClientPrefs.timebarShowSpeed && cpuControlled && ClientPrefs.timeBarType == 'Song Name') timeTxt.text = SONG.song + ' (' + playbackRateDecimal + 'x) (Bot)'; + } + } + + if(updateThePercent) { + var curTime:Float = Conductor.songPosition - ClientPrefs.noteOffset; + if(curTime < 0) curTime = 0; + songPercent = (curTime / songLength); + songPercentThing = FlxMath.roundDecimal(curTime / songLength * 100, ClientPrefs.percentDecimals); + if (ClientPrefs.hudType != 'Kade Engine' && ClientPrefs.hudType != 'Dave and Bambi') + { + timePercentTxt.text = songPercentThing + '% Completed'; + } + else + { + timePercentTxt.text = songPercentThing + '%'; + } + } + + // Conductor.lastSongPos = FlxG.sound.music.time; + } + + if (camZooming) + { + FlxG.camera.zoom = FlxMath.lerp(defaultCamZoom, FlxG.camera.zoom, CoolUtil.boundTo(1 - (elapsed * 3.125 * camZoomingDecay * playbackRate), 0, 1)); + camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, CoolUtil.boundTo(1 - (elapsed * 3.125 * camZoomingDecay * playbackRate), 0, 1)); + } + + FlxG.watch.addQuick("secShit", curSection); + FlxG.watch.addQuick("beatShit", curBeat); + FlxG.watch.addQuick("stepShit", curStep); + + // RESET = Quick Game Over Screen + if (!ClientPrefs.noReset && controls.RESET && canReset && !inCutscene && startedCountdown && !endingSong && !softlocked) + { + health = 0; + trace("RESET = True"); + } + doDeathCheck(); + + if (ClientPrefs.dynamicSpawnTime) { + spawnTime = 1800 / songSpeed; + } else { + spawnTime = 1800 * ClientPrefs.noteSpawnTime; + } +if (unspawnNotes[0] != null && (Conductor.songPosition + 1800 / songSpeed) >= firstNoteStrumTime && ClientPrefs.showNotes) +{ + spawnTime /= unspawnNotes[0].multSpeed; + + // Track the count of notes added + notesAddedCount = 0; + + for (i in 0...unspawnNotes.length) { + var dunceNote = unspawnNotes[i]; + if (dunceNote.strumTime - Conductor.songPosition < spawnTime) { + if (ClientPrefs.showNotes) { + // Add notes to 'notes' one by one if they meet the criteria + notes.insert(0, dunceNote); + } else { + notes.add(dunceNote); + } + dunceNote.spawned = true; + notesAddedCount++; + } + } + + if (notesAddedCount > 0) { + unspawnNotes.splice(0, notesAddedCount); + } +} + +if (unspawnNotes[0] != null && (Conductor.songPosition + 1800 / songSpeed) >= firstNoteStrumTime && !ClientPrefs.showNotes) +{ + spawnTime /= unspawnNotes[0].multSpeed; + + // Track the count of notes added + notesAddedCount = 0; + + for (i in 0...unspawnNotes.length) { + var daNote = unspawnNotes[i]; + if(daNote.mustPress && cpuControlled) { + if (daNote.strumTime + (ClientPrefs.communityGameBot ? FlxG.random.float(ClientPrefs.minCGBMS, ClientPrefs.maxCGBMS) : 0) <= Conductor.songPosition || daNote.isSustainNote && daNote.strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * daNote.earlyHitMult /2)) { + if (!ClientPrefs.showcaseMode || ClientPrefs.charsAndBG) goodNoteHit(daNote); + if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG && !daNote.wasGoodHit) + { + if (!daNote.isSustainNote) { + totalNotesPlayed += 1 * polyphony; + if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well + notesHitArray.push(1 * polyphony); + notesHitDateArray.push(Date.now()); + } + } + } + daNote.wasGoodHit = true; + } + } + + if (!daNote.mustPress && !daNote.hitByOpponent && !daNote.ignoreNote && daNote.strumTime <= Conductor.songPosition) + { + if (!ClientPrefs.showcaseMode || ClientPrefs.charsAndBG) { + if (!opponentChart) { + if (Paths.formatToSongPath(SONG.song) != 'tutorial' && !camZooming) + camZooming = true; + } + + var char:Character = dad; + if(opponentChart) char = boyfriend; + if(daNote.noteType == 'Hey!' && char.animOffsets.exists('hey')) { + char.playAnim('hey', true); + char.specialAnim = true; + char.heyTimer = 0.6; + } else if(!daNote.noAnimation) { + var altAnim:String = daNote.animSuffix; + + if (SONG.notes[curSection] != null) + { + if (SONG.notes[curSection].altAnim && !SONG.notes[curSection].gfSection && !opponentChart) { + altAnim = '-alt'; + } + } + + var char:Character = dad; + var animToPlay:String = singAnimations[Std.int(Math.abs(daNote.noteData))] + altAnim; + if(daNote.gfNote && ClientPrefs.charsAndBG) { + char = gf; + if (ClientPrefs.doubleGhost) + { + if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) + { + // potentially have jump anims? + var chord = noteRows[daNote.mustPress?0:1][daNote.row]; + var animNote = chord[0]; + var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; + if (gf.mostRecentRow != daNote.row) + { + gf.playAnim(realAnim, true); + } + + // if (daNote != animNote) + // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); + + + gf.mostRecentRow = daNote.row; + // dad.angle += 15; lmaooooo + doGhostAnim('gf', animToPlay); + } + } + } + if(opponentChart && ClientPrefs.charsAndBG) { + boyfriend.playAnim(animToPlay, true); + boyfriend.holdTimer = 0; + } + else if(char != null && !opponentChart && ClientPrefs.charsAndBG) + { + char.playAnim(animToPlay, true); + char.holdTimer = 0; + if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'oppt'); + if (ClientPrefs.doubleGhost) + { + if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) + { + // potentially have jump anims? + var chord = noteRows[daNote.mustPress?0:1][daNote.row]; + var animNote = chord[0]; + var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; + if (char.mostRecentRow != daNote.row) + { + char.playAnim(realAnim, true); + } + + // if (daNote != animNote) + // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); + + // dad.angle += 15; lmaooooo + if (!daNote.noAnimation && !daNote.gfNote) + { + if(char.mostRecentRow != daNote.row) + doGhostAnim('char', animToPlay + altAnim); + dadGhost.color = FlxColor.fromRGB(dad.healthColorArray[0] + 50, dad.healthColorArray[1] + 50, dad.healthColorArray[2] + 50); + dadGhostTween = FlxTween.tween(dadGhost, {alpha: 0}, 0.75, { + ease: FlxEase.linear, + onComplete: function(twn:FlxTween) + { + dadGhostTween = null; + } + }); + } + char.mostRecentRow = daNote.row; + } + } + else{ + char.playAnim(animToPlay + daNote.animSuffix, true); + // dad.angle = 0; + } + } + if (opponentChart && ClientPrefs.charsAndBG) + { + boyfriend.playAnim(animToPlay + daNote.animSuffix, true); + boyfriend.holdTimer = 0; + if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'bf'); + if (ClientPrefs.doubleGhost) + { + if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) + { + // potentially have jump anims? + var chord = noteRows[daNote.mustPress?0:1][daNote.row]; + var animNote = chord[0]; + var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; + if (boyfriend.mostRecentRow != daNote.row) + { + boyfriend.playAnim(realAnim, true); + } + + // if (daNote != animNote) + // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); + + boyfriend.mostRecentRow = daNote.row; + // dad.angle += 15; lmaooooo + doGhostAnim('bf', animToPlay); + } + else{ + boyfriend.playAnim(animToPlay + daNote.animSuffix, true); + // dad.angle = 0; + } + } + } + } + + if(ClientPrefs.oppNoteSplashes && !daNote.isSustainNote) + { + spawnNoteSplashOnNote(true, daNote); + } + + if (SONG.needsVoices) + vocals.volume = 1; + + var time:Float = 0.15 / playbackRate; + if (ClientPrefs.opponentLightStrum) + { + if(daNote.isSustainNote && (ClientPrefs.showNotes && !daNote.animation.curAnim.name.endsWith('end'))) { + time += 0.15; + } + var spr:StrumNote = opponentStrums.members[daNote.noteData]; + + if(spr != null) { + if ((ClientPrefs.colorQuants || ClientPrefs.rainbowNotes) && ClientPrefs.showNotes) { + spr.playAnim('confirm', true, daNote.colorSwap.hue, daNote.colorSwap.saturation, daNote.colorSwap.brightness); + } else { + spr.playAnim('confirm', true); + } + spr.resetAnim = time; + } + } + daNote.hitByOpponent = true; + + if (opponentDrain && health > 0.1) health -= daNote.hitHealth * hpDrainLevel * polyphony; + + callOnLuas('opponentNoteHit', [notes.members.indexOf(daNote), Math.abs(daNote.noteData), daNote.noteType, daNote.isSustainNote]); + callOnLuas((opponentChart ? 'goodNoteHitFix' : 'opponentNoteHitFix'), [notes.members.indexOf(daNote), Math.abs(daNote.noteData), daNote.noteType, daNote.isSustainNote]); + + if (!daNote.isSustainNote) + { + if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well + oppNotesHitArray.push(1 * polyphony); + oppNotesHitDateArray.push(Date.now()); + } + enemyHits += 1 * polyphony; + if (shouldKillNotes) + { + daNote.kill(); + } + if (ClientPrefs.showNotes) notes.remove(daNote, true); + if (shouldKillNotes) + { + daNote.destroy(); + } + } + } + if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) + { + if (!daNote.isSustainNote) { + enemyHits += 1 * polyphony; + if (ClientPrefs.showNPS) { + oppNotesHitArray.push(1 * polyphony); + oppNotesHitDateArray.push(Date.now()); + } + } + daNote.hitByOpponent = true; + } + } + } + + if (notesAddedCount > 0) { + for (i in 0...notesAddedCount) + unspawnNotes.shift(); + } +} + if (generatedMusic) + { + if(!inCutscene) + { + if(!cpuControlled && !softlocked) { + keyShit(); + } + else if (ClientPrefs.charsAndBG) { + if(boyfriend.animation.curAnim != null && boyfriend.holdTimer > Conductor.stepCrochet * (0.0011 / playbackRate) * boyfriend.singDuration && boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss')) { + boyfriend.dance(); + //boyfriend.animation.curAnim.finish(); + } + if (dad.animation.curAnim != null && dad.holdTimer > Conductor.stepCrochet * (0.0011 / playbackRate) * dad.singDuration && dad.animation.curAnim.name.startsWith('sing') && !dad.animation.curAnim.name.endsWith('miss')) { + dad.dance(); + } + } + + if(startedCountdown) + { + var fakeCrochet:Float = (60 / SONG.bpm) * 1000; + notes.forEachAlive(function(daNote:Note) + { + if (ClientPrefs.showNotes) + { + var strumGroup:FlxTypedGroup = playerStrums; + if(!daNote.mustPress) strumGroup = opponentStrums; + + var strumX:Float = strumGroup.members[daNote.noteData].x; + var strumY:Float = strumGroup.members[daNote.noteData].y; + var strumAngle:Float = strumGroup.members[daNote.noteData].angle; + var strumDirection:Float = strumGroup.members[daNote.noteData].direction; + var strumAlpha:Float = strumGroup.members[daNote.noteData].alpha; + var strumScroll:Bool = strumGroup.members[daNote.noteData].downScroll; + + strumX += daNote.offsetX; + strumY += daNote.offsetY; + strumAngle += daNote.offsetAngle; + strumAlpha *= daNote.multAlpha; + + if (strumScroll) //Downscroll + { + //daNote.y = (strumY + 0.45 * (Conductor.songPosition - daNote.strumTime) * songSpeed); + daNote.distance = (0.45 * (Conductor.songPosition - daNote.strumTime) * songSpeed * daNote.multSpeed); + } + else //Upscroll + { + //daNote.y = (strumY - 0.45 * (Conductor.songPosition - daNote.strumTime) * songSpeed); + daNote.distance = (-0.45 * (Conductor.songPosition - daNote.strumTime) * songSpeed * daNote.multSpeed); + } + + var angleDir = strumDirection * Math.PI / 180; + if (daNote.copyAngle) + daNote.angle = strumDirection - 90 + strumAngle; + + if(daNote.copyAlpha) + daNote.alpha = strumAlpha; + + if(daNote.copyX) + daNote.x = strumX + Math.cos(angleDir) * daNote.distance; + + if(daNote.copyY) + { + daNote.y = strumY + Math.sin(angleDir) * daNote.distance; + + //Jesus fuck this took me so much mother fucking time AAAAAAAAAA + if(strumScroll && daNote.isSustainNote && ClientPrefs.showNotes) + { + if (daNote.animation.curAnim.name.endsWith('end')) { + daNote.y += 10.5 * (fakeCrochet / 400) * 1.5 * songSpeed + (46 * (songSpeed - 1)); + daNote.y -= 46 * (1 - (fakeCrochet / 600)) * songSpeed; + if(PlayState.isPixelStage) { + daNote.y += 8 + (6 - daNote.originalHeightForCalcs) * PlayState.daPixelZoom; + } else { + daNote.y -= 19; + } + } + daNote.y += (Note.swagWidth / 2) - (60.5 * (songSpeed - 1)); + daNote.y += 27.5 * ((SONG.bpm / 100) - 1) * (songSpeed - 1); + } + } + var center:Float = strumY + Note.swagWidth / 2; + if(strumGroup.members[daNote.noteData].sustainReduce && daNote.isSustainNote && (daNote.mustPress || !daNote.ignoreNote) && + (!daNote.mustPress || (daNote.wasGoodHit || (daNote.prevNote.wasGoodHit && !daNote.canBeHit)))) + { + if (strumScroll) + { + if(daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= center) + { + var swagRect = new FlxRect(0, 0, daNote.frameWidth, daNote.frameHeight); + swagRect.height = (center - daNote.y) / daNote.scale.y; + swagRect.y = daNote.frameHeight - swagRect.height; + + daNote.clipRect = swagRect; + } + } + else + { + if (daNote.y + daNote.offset.y * daNote.scale.y <= center) + { + var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y); + swagRect.y = (center - daNote.y) / daNote.scale.y; + swagRect.height -= swagRect.y; + + daNote.clipRect = swagRect; + } + } + } + } + + if (!daNote.mustPress && !daNote.hitByOpponent && !daNote.ignoreNote && daNote.strumTime <= Conductor.songPosition) + { + if (!ClientPrefs.showcaseMode || ClientPrefs.charsAndBG) { + if (!opponentChart) { + if (Paths.formatToSongPath(SONG.song) != 'tutorial' && !camZooming) + camZooming = true; + } + + var char:Character = dad; + if(opponentChart) char = boyfriend; + if(daNote.noteType == 'Hey!' && char.animOffsets.exists('hey')) { + char.playAnim('hey', true); + char.specialAnim = true; + char.heyTimer = 0.6; + } else if(!daNote.noAnimation) { + var altAnim:String = daNote.animSuffix; + + if (SONG.notes[curSection] != null) + { + if (SONG.notes[curSection].altAnim && !SONG.notes[curSection].gfSection && !opponentChart) { + altAnim = '-alt'; + } + } + + var char:Character = dad; + var animToPlay:String = singAnimations[Std.int(Math.abs(daNote.noteData))] + altAnim; + if(daNote.gfNote && ClientPrefs.charsAndBG) { + char = gf; + if (ClientPrefs.doubleGhost) + { + if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) + { + // potentially have jump anims? + var chord = noteRows[daNote.mustPress?0:1][daNote.row]; + var animNote = chord[0]; + var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; + if (gf.mostRecentRow != daNote.row) + { + gf.playAnim(realAnim, true); + } + + // if (daNote != animNote) + // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); + + + gf.mostRecentRow = daNote.row; + // dad.angle += 15; lmaooooo + doGhostAnim('gf', animToPlay); + } + } + } + if(opponentChart && ClientPrefs.charsAndBG) { + boyfriend.playAnim(animToPlay, true); + boyfriend.holdTimer = 0; + } + else if(char != null && !opponentChart && ClientPrefs.charsAndBG) + { + char.playAnim(animToPlay, true); + char.holdTimer = 0; + if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'oppt'); + if (ClientPrefs.doubleGhost) + { + if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) + { + // potentially have jump anims? + var chord = noteRows[daNote.mustPress?0:1][daNote.row]; + var animNote = chord[0]; + var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; + if (char.mostRecentRow != daNote.row) + { + char.playAnim(realAnim, true); + } + + // if (daNote != animNote) + // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); + + // dad.angle += 15; lmaooooo + if (!daNote.noAnimation && !daNote.gfNote) + { + if(char.mostRecentRow != daNote.row) + doGhostAnim('char', animToPlay + altAnim); + dadGhost.color = FlxColor.fromRGB(dad.healthColorArray[0] + 50, dad.healthColorArray[1] + 50, dad.healthColorArray[2] + 50); + dadGhostTween = FlxTween.tween(dadGhost, {alpha: 0}, 0.75, { + ease: FlxEase.linear, + onComplete: function(twn:FlxTween) + { + dadGhostTween = null; + } + }); + } + char.mostRecentRow = daNote.row; + } + } + else{ + char.playAnim(animToPlay + daNote.animSuffix, true); + // dad.angle = 0; + } + } + if (opponentChart && ClientPrefs.charsAndBG) + { + boyfriend.playAnim(animToPlay + daNote.animSuffix, true); + boyfriend.holdTimer = 0; + if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'bf'); + if (ClientPrefs.doubleGhost) + { + if (!daNote.isSustainNote && noteRows[daNote.mustPress?0:1][daNote.row].length > 1) + { + // potentially have jump anims? + var chord = noteRows[daNote.mustPress?0:1][daNote.row]; + var animNote = chord[0]; + var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; + if (boyfriend.mostRecentRow != daNote.row) + { + boyfriend.playAnim(realAnim, true); + } + + // if (daNote != animNote) + // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); + + boyfriend.mostRecentRow = daNote.row; + // dad.angle += 15; lmaooooo + doGhostAnim('bf', animToPlay); + } + else{ + boyfriend.playAnim(animToPlay + daNote.animSuffix, true); + // dad.angle = 0; + } + } + } + } + + if(ClientPrefs.oppNoteSplashes && !daNote.isSustainNote) + { + spawnNoteSplashOnNote(true, daNote); + } + + if (SONG.needsVoices) + vocals.volume = 1; + + var time:Float = 0.15 / playbackRate; + if (ClientPrefs.opponentLightStrum) + { + if(daNote.isSustainNote && (ClientPrefs.showNotes && !daNote.animation.curAnim.name.endsWith('end'))) { + time += 0.15; + } + var spr:StrumNote = opponentStrums.members[daNote.noteData]; + + if(spr != null) { + if ((ClientPrefs.colorQuants || ClientPrefs.rainbowNotes) && ClientPrefs.showNotes) { + spr.playAnim('confirm', true, daNote.colorSwap.hue, daNote.colorSwap.saturation, daNote.colorSwap.brightness); + } else { + spr.playAnim('confirm', true); + } + spr.resetAnim = time; + } + } + daNote.hitByOpponent = true; + + if (opponentDrain && health > 0.1) health -= daNote.hitHealth * hpDrainLevel * polyphony; + + callOnLuas('opponentNoteHit', [notes.members.indexOf(daNote), Math.abs(daNote.noteData), daNote.noteType, daNote.isSustainNote]); + callOnLuas((opponentChart ? 'goodNoteHitFix' : 'opponentNoteHitFix'), [notes.members.indexOf(daNote), Math.abs(daNote.noteData), daNote.noteType, daNote.isSustainNote]); + + if (!daNote.isSustainNote) + { + if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well + oppNotesHitArray.push(1 * polyphony); + oppNotesHitDateArray.push(Date.now()); + } + enemyHits += 1 * polyphony; + if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0) updateRatingCounter(); + if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); + if (shouldKillNotes) + { + daNote.kill(); + } + if (ClientPrefs.showNotes) notes.remove(daNote, true); + if (shouldKillNotes) + { + daNote.destroy(); + } + } + } + if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) + { + if (!daNote.isSustainNote) { + enemyHits += 1 * polyphony; + if (ClientPrefs.showNPS) { + oppNotesHitArray.push(1 * polyphony); + oppNotesHitDateArray.push(Date.now()); + } + } + if (!daNote.isSustainNote) { + if (shouldKillNotes) + { + daNote.kill(); + } + if (shouldKillNotes) + { + daNote.destroy(); + } + } + } + } + + if(daNote.mustPress && cpuControlled) { + if(daNote.strumTime + (ClientPrefs.communityGameBot ? FlxG.random.float(ClientPrefs.minCGBMS, ClientPrefs.maxCGBMS) : 0) <= Conductor.songPosition || daNote.isSustainNote && daNote.strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * daNote.earlyHitMult /2)) { + if (!ClientPrefs.showcaseMode || ClientPrefs.charsAndBG) goodNoteHit(daNote); + if (ClientPrefs.showcaseMode && !ClientPrefs.charsAndBG) + { + if (!daNote.isSustainNote) { + totalNotesPlayed += 1 * polyphony; + if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well + notesHitArray.push(1 * polyphony); + notesHitDateArray.push(Date.now()); + } + if (shouldKillNotes) + { + daNote.kill(); + } + if (shouldKillNotes) + { + daNote.destroy(); + } + } + } + } + } + + // Kill extremely late notes and cause misses + if (Conductor.songPosition > noteKillOffset + daNote.strumTime) + { + if (daNote.mustPress && (!cpuControlled || cpuControlled && ClientPrefs.communityGameBot) &&!daNote.ignoreNote && !endingSong && (daNote.tooLate || !daNote.wasGoodHit)) { + noteMiss(daNote); + if (ClientPrefs.missSoundShit) + { + FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); + } + } + + daNote.active = false; + daNote.visible = false; + if (shouldKillNotes) + { + daNote.kill(); + } + notes.remove(daNote, true); + if (shouldKillNotes) + { + daNote.destroy(); + } + } + }); + } + else + { + notes.forEachAlive(function(daNote:Note) + { + daNote.canBeHit = false; + daNote.wasGoodHit = false; + }); + } + } + checkEventNote(); + } + + #if debug + if(!endingSong && !startingSong) { + if (FlxG.keys.justPressed.ONE) { + KillNotes(); + if (ClientPrefs.songLoading) FlxG.sound.music.onComplete(); + } + if(FlxG.keys.justPressed.TWO) { //Go 10 seconds into the future :O + setSongTime(Conductor.songPosition + 10000); + clearNotesBefore(Conductor.songPosition); + } + if(FlxG.keys.justPressed.THREE) { //Go 10 seconds into the future :O + setSongTime(Conductor.songPosition - 10000); + clearNotesBefore(Conductor.songPosition); + } + } + #end + + setOnLuas('cameraX', camFollowPos.x); + setOnLuas('cameraY', camFollowPos.y); + setOnLuas('botPlay', cpuControlled); + callOnLuas('onUpdatePost', [elapsed]); + for (i in shaderUpdates){ + i(elapsed); + } + } + + function openPauseMenu() + { + persistentUpdate = false; + persistentDraw = true; + paused = true; + + // 1 / 1000 chance for Gitaroo Man easter egg + /*if (FlxG.random.bool(0.1)) + { + // gitaroo man easter egg + cancelMusicFadeTween(); + MusicBeatState.switchState(new GitarooPause()); + } + else {*/ + if(FlxG.sound.music != null && ClientPrefs.songLoading) { + FlxG.sound.music.pause(); + vocals.pause(); + } + if (!ClientPrefs.charsAndBG) openSubState(new PauseSubState(0, 0)); + if (ClientPrefs.charsAndBG) openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); + //} + + #if desktop + DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); + #end + } + + function openChartEditor() + { + persistentUpdate = false; + paused = true; + cancelMusicFadeTween(); + MusicBeatState.switchState(new ChartingState()); + chartingMode = true; + #if desktop + DiscordClient.changePresence("Chart Editor", null, null, true); + #end + } + + public var isDead:Bool = false; //Don't mess with this on Lua!!! + function doDeathCheck(?skipHealthCheck:Bool = false) { + if (((skipHealthCheck && instakillOnMiss) || health <= 0) && !practiceMode && !isDead) + { + if (ClientPrefs.instaRestart) + { + restartSong(true); + } + var ret:Dynamic = callOnLuas('onGameOver', [], false); + if(ret != FunkinLua.Function_Stop) { + boyfriend.stunned = true; + deathCounter++; + + paused = true; + + if (ClientPrefs.songLoading) vocals.stop(); + if (ClientPrefs.songLoading) FlxG.sound.music.stop(); + + persistentUpdate = false; + persistentDraw = false; + for (tween in modchartTweens) { + tween.active = true; + } + for (timer in modchartTimers) { + timer.active = true; + } + if (ClientPrefs.charsAndBG) openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x - boyfriend.positionArray[0], boyfriend.getScreenPosition().y - boyfriend.positionArray[1], camFollowPos.x, camFollowPos.y)); + + if (!ClientPrefs.charsAndBG) openSubState(new GameOverSubstate(0, 0, 0, 0)); + + // MusicBeatState.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); + + #if desktop + // Game Over doesn't get his own variable because it's only used here + DiscordClient.changePresence("Game Over - " + detailsText, SONG.song + " (" + storyDifficultyText + ")", iconP2.getCharacter()); + #end + isDead = true; + return true; + } + } + return false; + } + + public function checkEventNote() { + while(eventNotes.length > 0) { + var leStrumTime:Float = eventNotes[0].strumTime; + if(Conductor.songPosition < leStrumTime) { + return; + } + + var value1:String = ''; + if(eventNotes[0].value1 != null) + value1 = eventNotes[0].value1; + + var value2:String = ''; + if(eventNotes[0].value2 != null) + value2 = eventNotes[0].value2; + + triggerEventNote(eventNotes[0].event, value1, value2); + eventNotes.shift(); + } + } + + public function getControl(key:String) { + var pressed:Bool = Reflect.getProperty(controls, key); + //trace('Control result: ' + pressed); + return pressed; + } + + public function triggerEventNote(eventName:String, value1:String, value2:String) { + switch(eventName) { + case 'Dadbattle Spotlight': + var val:Null = Std.parseInt(value1); + if(val == null) val = 0; + + switch(Std.parseInt(value1)) + { + case 1, 2, 3: //enable and target dad + if(val == 1) //enable + { + dadbattleBlack.visible = true; + dadbattleLight.visible = true; + dadbattleSmokes.visible = true; + defaultCamZoom += 0.12; + } + + var who:Character = dad; + if(val > 2) who = boyfriend; + //2 only targets dad + dadbattleLight.alpha = 0; + new FlxTimer().start(0.12, function(tmr:FlxTimer) { + dadbattleLight.alpha = 0.375; + }); + dadbattleLight.setPosition(who.getGraphicMidpoint().x - dadbattleLight.width / 2, who.y + who.height - dadbattleLight.height + 50); + + default: + dadbattleBlack.visible = false; + dadbattleLight.visible = false; + defaultCamZoom -= 0.12; + FlxTween.tween(dadbattleSmokes, {alpha: 0}, 1, {onComplete: function(twn:FlxTween) + { + dadbattleSmokes.visible = false; + }}); + } + + case 'Hey!': + if (ClientPrefs.charsAndBG) { + var value:Int = 2; + switch(value1.toLowerCase().trim()) { + case 'bf' | 'boyfriend' | '0': + value = 0; + case 'gf' | 'girlfriend' | '1': + value = 1; + } + + var time:Float = Std.parseFloat(value2); + if(Math.isNaN(time) || time <= 0) time = 0.6; + + if(value != 0) { + if(dad.curCharacter.startsWith('gf')) { //Tutorial GF is actually Dad! The GF is an imposter!! ding ding ding ding ding ding ding, dindinding, end my suffering + dad.playAnim('cheer', true); + dad.specialAnim = true; + dad.heyTimer = time; + } else if (gf != null) { + gf.playAnim('cheer', true); + gf.specialAnim = true; + gf.heyTimer = time; + } + + if(curStage == 'mall') { + bottomBoppers.animation.play('hey', true); + heyTimer = time; + } + } + if(value != 1) { + boyfriend.playAnim('hey', true); + boyfriend.specialAnim = true; + boyfriend.heyTimer = time; + } + } + + case 'Set GF Speed': + var value:Int = Std.parseInt(value1); + if(Math.isNaN(value) || value < 1) value = 1; + gfSpeed = value; + + case 'Philly Glow': + var lightId:Int = Std.parseInt(value1); + if(Math.isNaN(lightId)) lightId = 0; + + var doFlash:Void->Void = function() { + var color:FlxColor = FlxColor.WHITE; + if(!ClientPrefs.flashing) color.alphaFloat = 0.5; + + FlxG.camera.flash(color, 0.15, null, true); + }; + + var chars:Array = [boyfriend, gf, dad]; + switch(lightId) + { + case 0: + if(phillyGlowGradient.visible) + { + doFlash(); + if(ClientPrefs.camZooms) + { + FlxG.camera.zoom += 0.5; + camHUD.zoom += 0.1; + } + + blammedLightsBlack.visible = false; + phillyWindowEvent.visible = false; + phillyGlowGradient.visible = false; + phillyGlowParticles.visible = false; + curLightEvent = -1; + + for (who in chars) + { + who.color = FlxColor.WHITE; + } + phillyStreet.color = FlxColor.WHITE; + } + + case 1: //turn on + curLightEvent = FlxG.random.int(0, phillyLightsColors.length-1, [curLightEvent]); + var color:FlxColor = phillyLightsColors[curLightEvent]; + + if(!phillyGlowGradient.visible) + { + doFlash(); + if(ClientPrefs.camZooms) + { + FlxG.camera.zoom += 0.5; + camHUD.zoom += 0.1; + } + + blammedLightsBlack.visible = true; + blammedLightsBlack.alpha = 1; + phillyWindowEvent.visible = true; + phillyGlowGradient.visible = true; + phillyGlowParticles.visible = true; + } + else if(ClientPrefs.flashing) + { + var colorButLower:FlxColor = color; + colorButLower.alphaFloat = 0.25; + FlxG.camera.flash(colorButLower, 0.5, null, true); + } + + var charColor:FlxColor = color; + if(!ClientPrefs.flashing) charColor.saturation *= 0.5; + else charColor.saturation *= 0.75; + + for (who in chars) + { + who.color = charColor; + } + phillyGlowParticles.forEachAlive(function(particle:PhillyGlow.PhillyGlowParticle) + { + particle.color = color; + }); + phillyGlowGradient.color = color; + phillyWindowEvent.color = color; + + color.brightness *= 0.5; + phillyStreet.color = color; + + case 2: // spawn particles + if(!ClientPrefs.lowQuality) + { + var particlesNum:Int = FlxG.random.int(8, 12); + var width:Float = (2000 / particlesNum); + var color:FlxColor = phillyLightsColors[curLightEvent]; + for (j in 0...3) + { + for (i in 0...particlesNum) + { + var particle:PhillyGlow.PhillyGlowParticle = new PhillyGlow.PhillyGlowParticle(-400 + width * i + FlxG.random.float(-width / 5, width / 5), phillyGlowGradient.originalY + 200 + (FlxG.random.float(0, 125) + j * 40), color); + phillyGlowParticles.add(particle); + } + } + } + phillyGlowGradient.bop(); + } + + case 'Kill Henchmen': + killHenchmen(); + + case 'Enable Camera Bop': + camZooming = true; + + case 'Disable Camera Bop': + camZooming = false; + + case 'Camera Bopping': + var _interval:Int = Std.parseInt(value1); + if (Math.isNaN(_interval)) + _interval = 4; + var _intensity:Float = Std.parseFloat(value2); + if (Math.isNaN(_intensity)) + _intensity = 1; + + camBopIntensity = _intensity; + camBopInterval = _interval; + case 'Change Note Multiplier': + var noteMultiplier:Float = Std.parseFloat(value1); + if (Math.isNaN(noteMultiplier)) + noteMultiplier = 1; + + polyphony = noteMultiplier; + case 'Fake Song Length': + var fakelength:Float = Std.parseFloat(value1); + fakelength *= (Math.isNaN(fakelength) ? 1 : 1000); //don't multiply if value1 is null, but do if value1 is not null + var doTween:Bool = value2 == "true" ? true : false; + if (Math.isNaN(fakelength)) + if (ClientPrefs.songLoading) fakelength = FlxG.sound.music.length; + if (doTween = true) FlxTween.tween(this, {songLength: fakelength}, 1, {ease: FlxEase.expoOut}); + if (doTween = true && ClientPrefs.songLoading && (Math.isNaN(fakelength))) FlxTween.tween(this, {songLength: FlxG.sound.music.length}, 1, {ease: FlxEase.expoOut}); + songLength = fakelength; + + case 'Add Camera Zoom': + if(ClientPrefs.camZooms && FlxG.camera.zoom < 1.35) { + var camZoom:Float = Std.parseFloat(value1); + var hudZoom:Float = Std.parseFloat(value2); + if(Math.isNaN(camZoom)) camZoom = 0.015; + if(Math.isNaN(hudZoom)) hudZoom = 0.03; + + FlxG.camera.zoom += camZoom; + camHUD.zoom += hudZoom; + } + + case 'Trigger BG Ghouls': + if(curStage == 'schoolEvil' && !ClientPrefs.lowQuality) { + bgGhouls.dance(true); + bgGhouls.visible = true; + } + case 'Play Animation': + //trace('Anim to play: ' + value1); + var char:Character = dad; + switch(value2.toLowerCase().trim()) { + case 'bf' | 'boyfriend': + char = boyfriend; + case 'gf' | 'girlfriend': + char = gf; + default: + var val2:Int = Std.parseInt(value2); + if(Math.isNaN(val2)) val2 = 0; + + switch(val2) { + case 1: char = boyfriend; + case 2: char = gf; + } + } + + if (char != null) + { + char.playAnim(value1, true); + char.specialAnim = true; + } + + case 'Camera Follow Pos': + if(camFollow != null) + { + var val1:Float = Std.parseFloat(value1); + var val2:Float = Std.parseFloat(value2); + if(Math.isNaN(val1)) val1 = 0; + if(Math.isNaN(val2)) val2 = 0; + + isCameraOnForcedPos = false; + if(!Math.isNaN(Std.parseFloat(value1)) || !Math.isNaN(Std.parseFloat(value2))) { + camFollow.x = val1; + camFollow.y = val2; + isCameraOnForcedPos = true; + } + } + + case 'Alt Idle Animation': + var char:Character = dad; + switch(value1.toLowerCase().trim()) { + case 'gf' | 'girlfriend': + char = gf; + case 'boyfriend' | 'bf': + char = boyfriend; + default: + var val:Int = Std.parseInt(value1); + if(Math.isNaN(val)) val = 0; + + switch(val) { + case 1: char = boyfriend; + case 2: char = gf; + } + } + + if (char != null) + { + char.idleSuffix = value2; + char.recalculateDanceIdle(); + } + + case 'Screen Shake': + var valuesArray:Array = [value1, value2]; + var targetsArray:Array = [camGame, camHUD]; + for (i in 0...targetsArray.length) { + var split:Array = valuesArray[i].split(','); + var duration:Float = 0; + var intensity:Float = 0; + if(split[0] != null) duration = Std.parseFloat(split[0].trim()); + if(split[1] != null) intensity = Std.parseFloat(split[1].trim()); + if(Math.isNaN(duration)) duration = 0; + if(Math.isNaN(intensity)) intensity = 0; + + if(duration > 0 && intensity != 0) { + targetsArray[i].shake(intensity, duration); + } + } + + + case 'Change Character': + var charType:Int = 0; + switch(value1.toLowerCase().trim()) { + case 'gf' | 'girlfriend': + charType = 2; + case 'dad' | 'opponent': + charType = 1; + default: + charType = Std.parseInt(value1); + if(Math.isNaN(charType)) charType = 0; + } + + switch(charType) { + case 0: + if(boyfriend.curCharacter != value2) { + if(!boyfriendMap.exists(value2)) { + addCharacterToList(value2, charType); + } + + var lastAlpha:Float = boyfriend.alpha; + boyfriend.alpha = 0.00001; + boyfriend = boyfriendMap.get(value2); + boyfriend.alpha = lastAlpha; + iconP1.changeIcon(boyfriend.healthIcon); + } + setOnLuas('boyfriendName', boyfriend.curCharacter); + + case 1: + if(dad.curCharacter != value2) { + if(!dadMap.exists(value2)) { + addCharacterToList(value2, charType); + } + + var wasGf:Bool = dad.curCharacter.startsWith('gf'); + var lastAlpha:Float = dad.alpha; + dad.alpha = 0.00001; + dad = dadMap.get(value2); + if(!dad.curCharacter.startsWith('gf')) { + if(wasGf && gf != null) { + gf.visible = true; + } + } else if(gf != null) { + gf.visible = false; + } + dad.alpha = lastAlpha; + iconP2.changeIcon(dad.healthIcon); + if (ClientPrefs.hudType == 'VS Impostor') { + if (botplayTxt != null) FlxTween.color(botplayTxt, 1, botplayTxt.color, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])); + + if (!ClientPrefs.hideScore) FlxTween.color(scoreTxt, 1, scoreTxt.color, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])); + } + if (ClientPrefs.hudType == 'JS Engine') { + if (!ClientPrefs.hideScore) FlxTween.color(scoreTxt, 1, scoreTxt.color, FlxColor.fromRGB(dad.healthColorArray[0], dad.healthColorArray[1], dad.healthColorArray[2])); + } + } + setOnLuas('dadName', dad.curCharacter); + + case 2: + if(gf != null) + { + if(gf.curCharacter != value2) + { + if(!gfMap.exists(value2)) + { + addCharacterToList(value2, charType); + } + + var lastAlpha:Float = gf.alpha; + gf.alpha = 0.00001; + gf = gfMap.get(value2); + gf.alpha = lastAlpha; + } + setOnLuas('gfName', gf.curCharacter); + } + } + reloadHealthBarColors(); + + case 'BG Freaks Expression': + if(bgGirls != null) bgGirls.swapDanceType(); + + case 'Change Scroll Speed': + if (songSpeedType == "constant") + return; + var val1:Float = Std.parseFloat(value1); + var val2:Float = Std.parseFloat(value2); + if(Math.isNaN(val1)) val1 = 1; + if(Math.isNaN(val2)) val2 = 0; + + var newValue:Float = SONG.speed * ClientPrefs.getGameplaySetting('scrollspeed', 1) * val1; + + if(val2 <= 0) + { + songSpeed = newValue; + } + else + { + songSpeedTween = FlxTween.tween(this, {songSpeed: newValue}, val2 / playbackRate, {ease: FlxEase.linear, onComplete: + function (twn:FlxTween) + { + songSpeedTween = null; + } + }); + } + + case 'Set Property': + var killMe:Array = value1.split('.'); + if(killMe.length > 1) { + FunkinLua.setVarInArray(FunkinLua.getPropertyLoopThingWhatever(killMe, true, true), killMe[killMe.length-1], value2); + } else { + FunkinLua.setVarInArray(this, value1, value2); + } + } + callOnLuas('onEvent', [eventName, value1, value2]); + } + + function moveCameraSection():Void { + if(SONG.notes[curSection] == null) return; + + if (gf != null && SONG.notes[curSection].gfSection) + { + camFollow.set(gf.getMidpoint().x, gf.getMidpoint().y); + camFollow.x += gf.cameraPosition[0] + girlfriendCameraOffset[0]; + camFollow.y += gf.cameraPosition[1] + girlfriendCameraOffset[1]; + tweenCamIn(); + callOnLuas('onMoveCamera', ['gf']); + return; + } + + if (!SONG.notes[curSection].mustHitSection) + { + moveCamera(true); + callOnLuas('onMoveCamera', ['dad']); + } + else + { + moveCamera(false); + callOnLuas('onMoveCamera', ['boyfriend']); + } + } + + var cameraTwn:FlxTween; + public function moveCamera(isDad:Bool) + { + if(isDad) + { + camFollow.set(dad.getMidpoint().x + 150, dad.getMidpoint().y - 100); + camFollow.x += dad.cameraPosition[0] + opponentCameraOffset[0]; + camFollow.y += dad.cameraPosition[1] + opponentCameraOffset[1]; + tweenCamIn(); + } + else + { + camFollow.set(boyfriend.getMidpoint().x - 100, boyfriend.getMidpoint().y - 100); + camFollow.x -= boyfriend.cameraPosition[0] - boyfriendCameraOffset[0]; + camFollow.y += boyfriend.cameraPosition[1] + boyfriendCameraOffset[1]; + + if (Paths.formatToSongPath(SONG.song) == 'tutorial' && cameraTwn == null && FlxG.camera.zoom != 1) + { + cameraTwn = FlxTween.tween(FlxG.camera, {zoom: 1}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut, onComplete: + function (twn:FlxTween) + { + cameraTwn = null; + } + }); + } + } + } + + function tweenCamIn() { + if (Paths.formatToSongPath(SONG.song) == 'tutorial' && cameraTwn == null && FlxG.camera.zoom != 1.3) { + cameraTwn = FlxTween.tween(FlxG.camera, {zoom: 1.3}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut, onComplete: + function (twn:FlxTween) { + cameraTwn = null; + } + }); + } + } + + function snapCamFollowToPos(x:Float, y:Float) { + camFollow.set(x, y); + camFollowPos.setPosition(x, y); + } + + public function finishSong(?ignoreNoteOffset:Bool = false):Void + { + var finishCallback:Void->Void = endSong; //In case you want to change it in a specific song. + updateTime = false; + if (ClientPrefs.songLoading) FlxG.sound.music.volume = 0; + if (ClientPrefs.songLoading) vocals.volume = 0; + vocals.pause(); + if(ClientPrefs.noteOffset <= 0 || ignoreNoteOffset) { + finishCallback(); + } else { + finishTimer = new FlxTimer().start(ClientPrefs.noteOffset / 1000, function(tmr:FlxTimer) { + finishCallback(); + }); + } + } + public function no(?ignoreNoteOffset:Bool = false):Void + { + var loopedSong:Int = 1; + if (ClientPrefs.songLoading) FlxG.sound.music.volume = 0; + if (ClientPrefs.songLoading) vocals.volume = 0; + Conductor.songPosition = 8000 * loopedSong; + loopedSong++; + } + public function loopSongNoLimit(?ignoreNoteOffset:Bool = false):Void + { + if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; + if (!ClientPrefs.voiidTrollMode) { + if (playbackRate >= 65535) playbackRate += 3276.7; + if (playbackRate >= 32767 && playbackRate <= 65535) playbackRate += 1638.4; + if (playbackRate >= 16384 && playbackRate <= 32767) playbackRate += 819.2; + if (playbackRate >= 8192 && playbackRate <= 16384) playbackRate += 409.6; + if (playbackRate >= 4096 && playbackRate <= 8192) playbackRate += 204.8; + if (playbackRate >= 2048 && playbackRate <= 4096) playbackRate += 102.4; + if (playbackRate >= 1024 && playbackRate <= 2048) playbackRate += 51.2; + if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; + if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; + if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; + if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; + if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; + if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; + if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; + if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; + if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; + if (playbackRate <= 2) playbackRate += 0.05; + } + unspawnNotes = unspawnNotesCopy.copy(); + for (n in unspawnNotes) + { + n.active = true; + n.visible = true; + n.wasGoodHit = false; + n.canBeHit = false; + n.tooLate = false; + n.hitByOpponent = false; + n.spawned = false; + n.alpha = 1; + if (n.mustPress && !n.isSustainNote) + { + totalNotes += 1; + } else if (!n.mustPress && !n.isSustainNote) { + opponentNoteTotal += 1; + } + } + Conductor.songPosition = 0; + } + public function loopSongHighest(?ignoreNoteOffset:Bool = false):Void + { + if (playbackRate >= 10000) playbackRate = 10000; + if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; + if (!ClientPrefs.voiidTrollMode) { + if (playbackRate >= 5120 && playbackRate <= 10000) playbackRate += 409.6; + if (playbackRate >= 4096 && playbackRate <= 5120) playbackRate += 204.8; + if (playbackRate >= 2048 && playbackRate <= 4096) playbackRate += 102.4; + if (playbackRate >= 1024 && playbackRate <= 2048) playbackRate += 51.2; + if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; + if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; + if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; + if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; + if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; + if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; + if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; + if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; + if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; + if (playbackRate <= 2) playbackRate += 0.05; + } + unspawnNotes = unspawnNotesCopy.copy(); + for (n in unspawnNotes) + { + n.active = true; + n.visible = true; + n.wasGoodHit = false; + n.canBeHit = false; + n.tooLate = false; + n.hitByOpponent = false; + n.spawned = false; + n.alpha = 1; + if (n.mustPress && !n.isSustainNote) + { + totalNotes += 1; + } else if (!n.mustPress && !n.isSustainNote) { + opponentNoteTotal += 1; + } + } + Conductor.songPosition = 0; + } + public function loopSongHigh(?ignoreNoteOffset:Bool = false):Void + { + if (playbackRate >= 5120) playbackRate = 5120; + if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; + if (!ClientPrefs.voiidTrollMode) { + if (playbackRate >= 4096 && playbackRate <= 5119.99) playbackRate += 204.8; + if (playbackRate >= 2048 && playbackRate <= 4096) playbackRate += 102.4; + if (playbackRate >= 1024 && playbackRate <= 2048) playbackRate += 51.2; + if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; + if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; + if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; + if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; + if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; + if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; + if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; + if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; + if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; + if (playbackRate <= 2) playbackRate += 0.05; + } + unspawnNotes = unspawnNotesCopy.copy(); + for (n in unspawnNotes) + { + n.active = true; + n.visible = true; + n.wasGoodHit = false; + n.canBeHit = false; + n.tooLate = false; + n.hitByOpponent = false; + n.spawned = false; + n.alpha = 1; + if (n.mustPress && !n.isSustainNote) + { + totalNotes += 1; + } else if (!n.mustPress && !n.isSustainNote) { + opponentNoteTotal += 1; + } + } + Conductor.songPosition = 0; + } + public function loopSongMedium(?ignoreNoteOffset:Bool = false):Void + { + if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; + if (playbackRate >= 2048) playbackRate = 2048; + if (!ClientPrefs.voiidTrollMode) { + if (playbackRate >= 1024 && playbackRate <= 2047.99) playbackRate += 51.2; + if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; + if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; + if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; + if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; + if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; + if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; + if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; + if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; + if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; + if (playbackRate <= 2) playbackRate += 0.05; + } + unspawnNotes = unspawnNotesCopy.copy(); + for (n in unspawnNotes) + { + n.active = true; + n.visible = true; + n.wasGoodHit = false; + n.canBeHit = false; + n.tooLate = false; + n.hitByOpponent = false; + n.spawned = false; + n.alpha = 1; + if (n.mustPress && !n.isSustainNote) + { + totalNotes += 1; + } else if (!n.mustPress && !n.isSustainNote) { + opponentNoteTotal += 1; + } + } + Conductor.songPosition = 0; + } + public function loopSongLow(?ignoreNoteOffset:Bool = false):Void + { + if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; + if (playbackRate >= 1024) playbackRate = 1024; + if (!ClientPrefs.voiidTrollMode) { + if (playbackRate >= 512 && playbackRate <= 1024) playbackRate += 25.6; + if (playbackRate >= 256 && playbackRate <= 512) playbackRate += 12.8; + if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; + if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; + if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; + if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; + if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; + if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; + if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; + if (playbackRate <= 2) playbackRate += 0.05; + } + unspawnNotes = unspawnNotesCopy.copy(); + for (n in unspawnNotes) + { + n.active = true; + n.visible = true; + n.wasGoodHit = false; + n.canBeHit = false; + n.tooLate = false; + n.hitByOpponent = false; + n.spawned = false; + n.alpha = 1; + if (n.mustPress && !n.isSustainNote) + { + totalNotes += 1; + } else if (!n.mustPress && !n.isSustainNote) { + opponentNoteTotal += 1; + } + } + Conductor.songPosition = 0; + } + public function loopSongLower(?ignoreNoteOffset:Bool = false):Void + { + if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; + if (playbackRate >= 512) playbackRate = 512; + if (!ClientPrefs.voiidTrollMode) { + if (playbackRate >= 256 && playbackRate <= 511.9) playbackRate += 12.8; + if (playbackRate >= 128 && playbackRate <= 256) playbackRate += 6.4; + if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; + if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; + if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; + if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; + if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; + if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; + if (playbackRate <= 2) playbackRate += 0.05; + } + unspawnNotes = unspawnNotesCopy.copy(); + for (n in unspawnNotes) + { + n.active = true; + n.visible = true; + n.wasGoodHit = false; + n.canBeHit = false; + n.tooLate = false; + n.hitByOpponent = false; + n.spawned = false; + n.alpha = 1; + n.clipRect = null; + if (n.mustPress && !n.isSustainNote) + { + totalNotes += 1; + } else if (!n.mustPress && !n.isSustainNote) { + opponentNoteTotal += 1; + } + } + Conductor.songPosition = 0; + } + public function loopSongLowest(?ignoreNoteOffset:Bool = false):Void + { + if (ClientPrefs.voiidTrollMode) playbackRate *= 1.05; + if (playbackRate >= 256) playbackRate = 256; + if (!ClientPrefs.voiidTrollMode) { + if (playbackRate >= 128 && playbackRate <= 255) playbackRate += 6.4; + if (playbackRate >= 64 && playbackRate <= 128) playbackRate += 3.2; + if (playbackRate >= 32 && playbackRate <= 64) playbackRate += 1.6; + if (playbackRate >= 16 && playbackRate <= 32) playbackRate += 0.8; + if (playbackRate >= 8 && playbackRate <= 16) playbackRate += 0.4; + if (playbackRate >= 4 && playbackRate <= 8) playbackRate += 0.2; + if (playbackRate >= 2 && playbackRate <= 4) playbackRate += 0.1; + if (playbackRate <= 2) playbackRate += 0.05; + } + unspawnNotes = unspawnNotesCopy.copy(); + for (n in unspawnNotes) + { + n.active = true; + n.visible = true; + n.wasGoodHit = false; + n.canBeHit = false; + n.tooLate = false; + n.hitByOpponent = false; + n.spawned = false; + n.alpha = 1; + n.clipRect = null; + if (n.mustPress && !n.isSustainNote) + { + totalNotes += 1; + } else if (!n.mustPress && !n.isSustainNote) { + opponentNoteTotal += 1; + } + } + Conductor.songPosition = 0; + } + + public function infiniteLoop(?ignoreNoteOffset:Bool = false):Void + { + unspawnNotes = unspawnNotesCopy.copy(); + for (n in unspawnNotes) + { + n.active = true; + n.visible = true; + n.wasGoodHit = false; + n.canBeHit = false; + n.tooLate = false; + n.hitByOpponent = false; + n.spawned = false; + n.alpha = 1; + n.clipRect = null; + if (n.mustPress && !n.isSustainNote) + { + totalNotes += 1; + } else if (!n.mustPress && !n.isSustainNote) { + opponentNoteTotal += 1; + } + } + Conductor.songPosition = 0; + } + public function infiniteLoopLua(startPoint:Float = 0):Void + { + unspawnNotes = unspawnNotesCopy.copy(); + for (n in unspawnNotes) + { + if (n.strumTime >= Conductor.songPosition) + { + n.active = true; + n.visible = true; + n.wasGoodHit = false; + n.tooLate = false; + n.canBeHit = false; + n.hitByOpponent = false; + n.spawned = false; + n.alpha = 1; + n.clipRect = null; + if (n.mustPress && !n.isSustainNote) + { + totalNotes += 1; + } else if (!n.mustPress && !n.isSustainNote) { + opponentNoteTotal += 1; + } + } else { + n.active = false; + n.visible = false; + n.wasGoodHit = true; + n.tooLate = false; + n.canBeHit = false; + n.hitByOpponent = true; + n.spawned = true; + n.alpha = 0; + n.clipRect = null; + } + } + } + + + public var transitioning = false; + public var endedTheSong = false; + public function endSong():Void + { + //Should kill you if you tried to cheat + if(!startingSong) { + notes.forEach(function(daNote:Note) { + if(daNote.strumTime < songLength - Conductor.safeZoneOffset) { + health -= 0.05 * healthLoss; + } + }); + { + for (daNote in unspawnNotes) { + if(daNote.strumTime < songLength - Conductor.safeZoneOffset) { + health -= 0.05 * healthLoss; + } + } + } + if(doDeathCheck()) { + return; + } + } + if (!endedTheSong) + { + Conductor.songPosition = 0; //so that it doesnt skip the results screen + if (!ClientPrefs.resultsScreen) { + #if android + androidControls.visible = false; + #end + endedTheSong = true; + timeBarBG.visible = false; + timeBar.visible = false; + timeTxt.visible = false; + canPause = false; + endingSong = true; + camZooming = false; + inCutscene = false; + updateTime = false; + } + if (ClientPrefs.resultsScreen && !isStoryMode) { + new FlxTimer().start(0.02, function(tmr:FlxTimer) { + endedTheSong = true; + }); + persistentUpdate = false; + persistentDraw = true; + paused = true; + } + openSubState(new ResultsScreenSubState([marvs, sicks, goods, bads, shits], Std.int(songScore), songMisses, Highscore.floorDecimal(ratingPercent * 100, 2), + ratingName + (' [' + ratingFC + '] '))); + } + if (endedTheSong || !ClientPrefs.resultsScreen) + { + #if android + androidControls.visible = false; + #end + timeBarBG.visible = false; + timeBar.visible = false; + timeTxt.visible = false; + canPause = false; + endingSong = true; + camZooming = false; + inCutscene = false; + updateTime = false; + + deathCounter = 0; + seenCutscene = false; + + #if ACHIEVEMENTS_ALLOWED + if(achievementObj != null) { + return; + } else { + var achieve:String = checkForAchievement(['week1_nomiss', 'week2_nomiss', 'week3_nomiss', 'week4_nomiss', + 'week5_nomiss', 'week6_nomiss', 'week7_nomiss', 'ur_bad', + 'ur_good', 'hype', 'two_keys', 'toastie', 'debugger']); + var customAchieves:String = checkForAchievement(achievementWeeks); + + if(achieve != null || customAchieves != null) { + startAchievement(achieve); + return; + } + } + #end + + var ret:Dynamic = callOnLuas('onEndSong', [], false); + if(ret != FunkinLua.Function_Stop && !transitioning) { + if (SONG.validScore && !cpuControlled && !playerIsCheating && ClientPrefs.comboMultLimit <= 10 && ClientPrefs.safeFrames <= 10) + { + #if !switch + var percent:Float = ratingPercent; + if(Math.isNaN(percent)) percent = 0; + Highscore.saveScore(SONG.song, Std.int(songScore), storyDifficulty, percent); + #end + } + playbackRate = 1; + + if (chartingMode) + { + openChartEditor(); + return; + } + + if (isStoryMode) + { + campaignScore += songScore; + campaignMisses += songMisses; + + storyPlaylist.remove(storyPlaylist[0]); + + if (storyPlaylist.length <= 0) + { + WeekData.loadTheFirstEnabledMod(); + FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic)); + + cancelMusicFadeTween(); + if(FlxTransitionableState.skipNextTransIn) { + CustomFadeTransition.nextCamera = null; + } + if (ClientPrefs.resultsScreen) + openSubState(new ResultsScreenSubState([marvs, sicks, goods, bads, shits], Std.int(campaignScore), songMisses, + Highscore.floorDecimal(ratingPercent * 100, 2), ratingName + (' [' + ratingFC + '] '))); + else + MusicBeatState.switchState(new StoryMenuState()); + + // if () + if(!ClientPrefs.getGameplaySetting('practice', false) && !ClientPrefs.getGameplaySetting('botplay', false)) { + StoryMenuState.weekCompleted.set(WeekData.weeksList[storyWeek], true); + + if (SONG.validScore) + { + Highscore.saveWeekScore(WeekData.getWeekFileName(), Std.int(campaignScore), storyDifficulty); + } + + FlxG.save.data.weekCompleted = StoryMenuState.weekCompleted; + FlxG.save.flush(); + } + changedDifficulty = false; + } + else + { + var difficulty:String = CoolUtil.getDifficultyFilePath(); + + trace('LOADING NEXT SONG'); + trace(Paths.formatToSongPath(PlayState.storyPlaylist[0]) + difficulty); + + var winterHorrorlandNext = (Paths.formatToSongPath(SONG.song) == "eggnog"); + if (winterHorrorlandNext) + { + 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; + prevCamFollowPos = camFollowPos; + + PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0] + difficulty, PlayState.storyPlaylist[0]); + FlxG.sound.music.stop(); + + if(winterHorrorlandNext) { + new FlxTimer().start(1.5, function(tmr:FlxTimer) { + cancelMusicFadeTween(); + LoadingState.loadAndSwitchState(new PlayState()); + }); + } else { + cancelMusicFadeTween(); + LoadingState.loadAndSwitchState(new PlayState()); + } + } + } + else + { + trace('WENT BACK TO FREEPLAY??'); + WeekData.loadTheFirstEnabledMod(); + cancelMusicFadeTween(); + if(FlxTransitionableState.skipNextTransIn) { + CustomFadeTransition.nextCamera = null; + } + MusicBeatState.switchState(new FreeplayState()); + FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic)); + changedDifficulty = false; + } + } + transitioning = true; + } + } + + #if ACHIEVEMENTS_ALLOWED + var achievementObj:AchievementObject = null; + function startAchievement(achieve:String) { + achievementObj = new AchievementObject(achieve, camOther); + achievementObj.onFinish = achievementEnd; + add(achievementObj); + trace('Giving achievement ' + achieve); + } + function achievementEnd():Void + { + achievementObj = null; + if(endingSong && !inCutscene) { + endSong(); + } + } + #end + + public function KillNotes() { + while(notes.length > 0) { + var daNote:Note = notes.members[0]; + daNote.active = false; + daNote.visible = false; + + daNote.kill(); + notes.remove(daNote, true); + daNote.destroy(); + } + unspawnNotes = []; + eventNotes = []; + } + + public static function restartSong(noTrans:Bool = true) + { + PlayState.instance.paused = true; // For lua + if (ClientPrefs.songLoading) FlxG.sound.music.volume = 0; + if (ClientPrefs.songLoading) PlayState.instance.vocals.volume = 0; + + if(noTrans) + { + FlxTransitionableState.skipNextTransOut = true; + FlxG.resetState(); + } + else + { + MusicBeatState.resetState(); + } + } + + public var totalPlayed:Int = 0; + public var totalNotesHit:Float = 0.0; + public var totalNotes:Int = 0; + + public var showCombo:Bool = true; + public var showComboNum:Bool = true; + public var showRating:Bool = true; + + private function cachePopUpScore() + { + var pixelShitPart1:String = ''; + var pixelShitPart2:String = ''; + if (isPixelStage) + { + pixelShitPart1 = 'pixelUI/'; + pixelShitPart2 = '-pixel'; + } + if (ClientPrefs.ratingType == 'Doki Doki+') + { + pixelShitPart1 = 'dokistuff/'; + pixelShitPart2 = ''; + } + if (ClientPrefs.ratingType == 'Tails Gets Trolled V4') + { + pixelShitPart1 = 'tgtstuff/'; + pixelShitPart2 = ''; + } + if (ClientPrefs.ratingType == 'Kade Engine') + { + pixelShitPart1 = 'kadethings/'; + pixelShitPart2 = ''; + } + if (allSicks) + { + pixelShitPart1 = 'goldstuff/'; + pixelShitPart2 = ''; + } + if (allSicks || !allSicks && ClientPrefs.marvRateColor == 'Golden' && !ClientPrefs.noMarvJudge) + { + Paths.image(pixelShitPart1 + "marv" + pixelShitPart2); + } + if (!allSicks && ClientPrefs.marvRateColor == 'Rainbow' && !ClientPrefs.noMarvJudge) + { + Paths.image(pixelShitPart1 + "marv" + pixelShitPart2); + } + Paths.image(pixelShitPart1 + "sick" + pixelShitPart2); + Paths.image(pixelShitPart1 + "good" + pixelShitPart2); + Paths.image(pixelShitPart1 + "bad" + pixelShitPart2); + Paths.image(pixelShitPart1 + "shit" + pixelShitPart2); + Paths.image(pixelShitPart1 + "combo" + pixelShitPart2); + + for (i in 0...10) { + Paths.image(pixelShitPart1 + 'num' + i + pixelShitPart2); + } + } + + function doGhostAnim(char:String, animToPlay:String) + { + if (ClientPrefs.doubleGhost || ClientPrefs.charsAndBG) + { + var ghost:FlxSprite = dadGhost; + var player:Character = dad; + + switch(char.toLowerCase().trim()) + { + case 'bf': + ghost = bfGhost; + player = boyfriend; + case 'dad': + ghost = dadGhost; + player = dad; + case 'gf': + ghost = gfGhost; + player = gf; + } + + + ghost.frames = player.frames; + ghost.animation.copyFrom(player.animation); + ghost.x = player.x; + ghost.y = player.y; + ghost.animation.play(animToPlay, true); + ghost.offset.set(player.animOffsets.get(animToPlay)[0], player.animOffsets.get(animToPlay)[1]); + ghost.flipX = player.flipX; + ghost.flipY = player.flipY; + ghost.blend = HARDLIGHT; + ghost.alpha = 0.8; + ghost.visible = true; + + if (FlxG.camera.zoom < 1.35 && ClientPrefs.camZooms && camZooming && ClientPrefs.doubleGhostZoom) + { + FlxG.camera.zoom += 0.0075; + camHUD.zoom += 0.015; + } + + switch (char.toLowerCase().trim()) + { + case 'bf': + if (bfGhostTween != null) + bfGhostTween.cancel(); + ghost.color = FlxColor.fromRGB(boyfriend.healthColorArray[0] + 50, boyfriend.healthColorArray[1] + 50, boyfriend.healthColorArray[2] + 50); + bfGhostTween = FlxTween.tween(bfGhost, {alpha: 0}, 0.75, { + ease: FlxEase.linear, + onComplete: function(twn:FlxTween) + { + bfGhostTween = null; + } + }); + + case 'dad': + if (dadGhostTween != null) + dadGhostTween.cancel(); + ghost.color = FlxColor.fromRGB(dad.healthColorArray[0] + 50, dad.healthColorArray[1] + 50, dad.healthColorArray[2] + 50); + dadGhostTween = FlxTween.tween(dadGhost, {alpha: 0}, 0.75, { + ease: FlxEase.linear, + onComplete: function(twn:FlxTween) + { + dadGhostTween = null; + } + }); + case 'gf': + if (gfGhostTween != null) + gfGhostTween.cancel(); + ghost.color = FlxColor.fromRGB(gf.healthColorArray[0] + 50, gf.healthColorArray[1] + 50, gf.healthColorArray[2] + 50); + gfGhostTween = FlxTween.tween(gfGhost, {alpha: 0}, 0.75, { + ease: FlxEase.linear, + onComplete: function(twn:FlxTween) + { + gfGhostTween = null; + } + }); + } + } + } + + private function popUpScore(note:Note = null):Void + { + var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition + ClientPrefs.ratingOffset); + //trace(noteDiff, ' ' + Math.abs(note.strumTime - Conductor.songPosition)); + if (note != null && note.isSustainNote && ClientPrefs.holdNoteHits) noteDiff = 0; + 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.35; + // + if(ClientPrefs.scoreZoom && !ClientPrefs.hideScore && !cpuControlled) + { + if(scoreTxtTween != null) { + scoreTxtTween.cancel(); + } + scoreTxt.scale.x = 1.075; + scoreTxt.scale.y = 1.075; + scoreTxtTween = FlxTween.tween(scoreTxt.scale, {x: 1, y: 1}, 0.2, { + onComplete: function(twn:FlxTween) { + scoreTxtTween = null; + } + }); + } + + var rating:FlxSprite = new FlxSprite(); + var score:Float = 500 * polyphony; + + if (noteDiff > ClientPrefs.marvWindow && noteDiff < ClientPrefs.sickWindow && !ClientPrefs.noMarvJudge) maxScore -= 150 * Std.int(polyphony); //if you enable marvelous judges and hit a sick, lower the max score by 150 points. otherwise it won't make sense + + //tryna do MS based judgment due to popular demand + var daRating:Rating = Conductor.judgeNote(note, noteDiff / playbackRate); + + if (!ClientPrefs.complexAccuracy) totalNotesHit += daRating.ratingMod; + if (ClientPrefs.complexAccuracy) totalNotesHit += wife; + note.ratingMod = daRating.ratingMod; + if(!note.ratingDisabled) daRating.increase(); + note.rating = daRating.name; + score = daRating.score; + + if (goods > 0 || bads > 0 || shits > 0 || songMisses > 0 && ClientPrefs.goldSickSFC || !ClientPrefs.goldSickSFC) + { + // if it isn't a sick, and you had a sick combo, then it becomes not sick :( + if (allSicks) + allSicks = false; + + } + if (noteDiff > ClientPrefs.badWindow && ClientPrefs.shitGivesMiss && ClientPrefs.ratingIntensity == 'Normal') + { + noteMiss(note); + } + if (noteDiff > ClientPrefs.goodWindow && ClientPrefs.shitGivesMiss && ClientPrefs.ratingIntensity == 'Harsh') + { + noteMiss(note); + } + if (noteDiff > ClientPrefs.sickWindow && ClientPrefs.shitGivesMiss && ClientPrefs.ratingIntensity == 'Very Harsh') + { + noteMiss(note); + } + if (ClientPrefs.healthGainType == 'VS Impostor') { + if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) + { + health += note.hitHealth * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) + { + health += note.hitHealth * healthGain * polyphony; + } + if (note.isSustainNote) + { + health += note.hitHealth * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.sickWindow) + { + health += note.hitHealth * 0.5 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.goodWindow) + { + health += note.hitHealth * 0.25 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.badWindow) + { + health += note.hitHealth * 0.1 * healthGain * polyphony; + } + } + if (ClientPrefs.healthGainType == 'Leather Engine') { + if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) //you hit a marvelous!! + { + health += 0.012 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) + { + health += 0.012 * healthGain * polyphony; //you hit a sick! + } + if (noteDiff > ClientPrefs.sickWindow) //you hit a good rating + { + health += -0.008 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.goodWindow) //you hit a bad rating + { + health += -0.018 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.badWindow) //you hit a shit rating + { + health += -0.23; + } + } + if (ClientPrefs.healthGainType == 'Kade (1.4.2 to 1.6)') { + if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) + { + health += 0.1 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) + { + health += 0.1 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.sickWindow) + { + health += 0.04 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.goodWindow) + { + health -= 0.06 * healthLoss; + } + if (noteDiff > ClientPrefs.badWindow) + { + health -= 0.2 * healthLoss; + } + } + if (ClientPrefs.healthGainType == 'Doki Doki+') { + if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) + { + health += 0.077 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) + { + health += 0.077 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.sickWindow) + { + health += 0.04 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.goodWindow) + { + health -= 0.06 * healthLoss; + } + if (noteDiff > ClientPrefs.badWindow) + { + health -= 0.1 * healthLoss; + } + } + if (ClientPrefs.healthGainType == 'Kade (1.6+)') { + if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) + { + health += 0.017 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) + { + health += 0.017 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.sickWindow) + { + health += 0; + } + if (noteDiff > ClientPrefs.goodWindow) + { + health -= 0.03 * healthLoss; + } + if (noteDiff > ClientPrefs.badWindow) + { + health -= 0.06 * healthLoss; + } + } + if (ClientPrefs.healthGainType == 'Kade (1.2)') { + if (noteDiff < ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) + { + health += 0.023 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.marvWindow || noteDiff < ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) + { + health += 0.023 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.sickWindow) + { + health += 0.004 * healthGain * polyphony; + } + if (noteDiff > ClientPrefs.goodWindow) + { + health -= 0; + } + if (noteDiff > ClientPrefs.badWindow) + { + health -= 0; + } + } + + if(daRating.noteSplash && !note.noteSplashDisabled) + { + spawnNoteSplashOnNote(false, note); + } + + if(!practiceMode) { + songScore += score * comboMultiplier * polyphony; + if(!note.ratingDisabled || cpuControlled && !ClientPrefs.lessBotLag && !note.ratingDisabled) + { + songHits++; + totalPlayed++; + if(!cpuControlled || cpuControlled && ClientPrefs.communityGameBot) { + RecalculateRating(false); + } + } + } + + var pixelShitPart1:String = ""; + var pixelShitPart2:String = ''; + + if (PlayState.isPixelStage) + { + pixelShitPart1 = 'pixelUI/'; + pixelShitPart2 = '-pixel'; + } + if (ClientPrefs.ratingType == 'Doki Doki+') + { + pixelShitPart1 = 'dokistuff/'; + pixelShitPart2 = ''; + } + if (ClientPrefs.ratingType == 'Tails Gets Trolled V4') + { + pixelShitPart1 = 'tgtstuff/'; + pixelShitPart2 = ''; + } + if (ClientPrefs.ratingType == 'Kade Engine') + { + pixelShitPart1 = 'kadethings/'; + pixelShitPart2 = ''; + } + if (allSicks && ClientPrefs.marvRateColor == 'Golden' && noteDiff < ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && !ClientPrefs.noMarvJudge) + { + pixelShitPart1 = 'goldstuff/'; + pixelShitPart2 = ''; + } + if (!allSicks && ClientPrefs.marvRateColor == 'Golden' && noteDiff < ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && !ClientPrefs.noMarvJudge) + { + pixelShitPart1 = 'goldstuff/'; + pixelShitPart2 = ''; + } + if (!allSicks && ClientPrefs.marvRateColor == 'Rainbow' && noteDiff < ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && !ClientPrefs.noMarvJudge) + { + pixelShitPart1 = ''; + pixelShitPart2 = ''; + } + if (ClientPrefs.ratesAndCombo) { + rating.loadGraphic(Paths.image(pixelShitPart1 + daRating.image + pixelShitPart2)); + rating.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); + rating.screenCenter(); + rating.x = coolText.x - 40; + rating.y -= 60; + rating.acceleration.y = 550 * playbackRate * playbackRate; + rating.velocity.y -= FlxG.random.int(140, 175) * playbackRate; + rating.velocity.x -= FlxG.random.int(0, 10) * playbackRate; + rating.visible = (!ClientPrefs.hideHud && showRating); + rating.x += ClientPrefs.comboOffset[0]; + rating.y -= ClientPrefs.comboOffset[1]; +if (!allSicks && ClientPrefs.colorRatingFC && marvs > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.noMarvJudge) + { + rating.color = judgeColours.get('marv'); + } +if (!allSicks && ClientPrefs.colorRatingFC && sicks > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.marvRateColor != 'Golden' && !ClientPrefs.noMarvJudge) + { + rating.color = judgeColours.get('sick'); + } +if (!allSicks && ClientPrefs.colorRatingFC && goods > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') + { + rating.color = judgeColours.get('good'); + } +if (!allSicks && ClientPrefs.colorRatingFC && bads > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') + { + rating.color = judgeColours.get('bad'); + } +if (!allSicks && ClientPrefs.colorRatingFC && shits > 0 && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') + { + rating.color = judgeColours.get('shit'); + } +if (!allSicks && ClientPrefs.colorRatingHit && noteDiff > ClientPrefs.marvWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.noMarvJudge) + { + rating.color = judgeColours.get('marv'); + } +if (!allSicks && ClientPrefs.colorRatingHit && noteDiff > ClientPrefs.marvWindow && noteDiff < ClientPrefs.sickWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.marvRateColor != 'Golden' && !ClientPrefs.noMarvJudge) + { + rating.color = judgeColours.get('sick'); + } +if (!allSicks && ClientPrefs.colorRatingHit && noteDiff > ClientPrefs.sickWindow && noteDiff < ClientPrefs.goodWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') + { + rating.color = judgeColours.get('good'); + } +if (!allSicks && ClientPrefs.colorRatingHit && bads > 0 && noteDiff > ClientPrefs.goodWindow && noteDiff < ClientPrefs.badWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') + { + rating.color = judgeColours.get('bad'); + } +if (!allSicks && ClientPrefs.colorRatingHit && noteDiff > ClientPrefs.badWindow && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+') + { + rating.color = judgeColours.get('shit'); + } + insert(members.indexOf(strumLineNotes), rating); + + if (ClientPrefs.showMS && !ClientPrefs.hideHud) { + FlxTween.cancelTweensOf(msTxt); + FlxTween.cancelTweensOf(msTxt.scale); + var msTiming:Float = note.strumTime - Conductor.songPosition + ClientPrefs.ratingOffset; + var time = (Conductor.stepCrochet * 0.001); //ms popup shit + msTxt.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); + msTxt.visible = true; + msTxt.screenCenter(); + msTxt.x = (ClientPrefs.comboPopup ? coolText.x + 280 : coolText.x + 80); + msTxt.alpha = 1; + msTxt.text = FlxMath.roundDecimal(-msTiming, 3) + " MS"; + if (cpuControlled && !ClientPrefs.communityGameBot) msTxt.text = "0 MS (Bot)"; + msTxt.x += ClientPrefs.comboOffset[0]; + msTxt.y -= ClientPrefs.comboOffset[1]; + if (combo >= 1000000) msTxt.x += 30; + if (combo >= 100000) msTxt.x += 30; + if (combo >= 10000) msTxt.x += 30; + FlxTween.tween(msTxt, + {y: msTxt.y + 8}, + 0.1 / playbackRate, + {onComplete: function(_){ + + FlxTween.tween(msTxt, {alpha: 0}, time, { + // ease: FlxEase.circOut, + onComplete: function(_){msTxt.visible = false;}, + startDelay: time * 5 / playbackRate + }); + } + }); + if (noteDiff <= ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) msTxt.color = FlxColor.YELLOW; + if (noteDiff <= ClientPrefs.sickWindow && ClientPrefs.noMarvJudge) msTxt.color = FlxColor.CYAN; + if (noteDiff <= ClientPrefs.sickWindow && noteDiff >= ClientPrefs.marvWindow && !ClientPrefs.noMarvJudge) msTxt.color = FlxColor.CYAN; + if (noteDiff >= ClientPrefs.sickWindow) msTxt.color = FlxColor.LIME; + if (noteDiff >= ClientPrefs.goodWindow) msTxt.color = FlxColor.ORANGE; + if (noteDiff >= ClientPrefs.badWindow) msTxt.color = FlxColor.RED; + if (!msTxt.visible) msTxt.color = FlxColor.WHITE; + } + var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); + comboSpr.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); + comboSpr.screenCenter(); + comboSpr.x = coolText.x; + comboSpr.acceleration.y = FlxG.random.int(200, 300) * playbackRate * playbackRate; + comboSpr.velocity.y -= FlxG.random.int(140, 160) * playbackRate; + comboSpr.visible = (!ClientPrefs.hideHud && showCombo); + comboSpr.x += ClientPrefs.comboOffset[0]; + comboSpr.y -= ClientPrefs.comboOffset[1]; + comboSpr.y += 60; + comboSpr.color = rating.color; + comboSpr.velocity.x += FlxG.random.int(1, 10) * playbackRate; + if (ClientPrefs.comboPopup && !cpuControlled) + { + insert(members.indexOf(strumLineNotes), comboSpr); + } + if (!ClientPrefs.comboStacking) + { + if (lastCombo != null) lastCombo.kill(); + lastCombo = comboSpr; + } + + if (!ClientPrefs.comboStacking) + { + if (lastRating != null) lastRating.kill(); + lastRating = rating; + } + + if (!PlayState.isPixelStage) + { + rating.setGraphicSize(Std.int(rating.width * 0.7)); + rating.antialiasing = ClientPrefs.globalAntialiasing; + comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7)); + comboSpr.antialiasing = ClientPrefs.globalAntialiasing; + } + else + { + rating.setGraphicSize(Std.int(rating.width * daPixelZoom * 0.85)); + comboSpr.setGraphicSize(Std.int(comboSpr.width * daPixelZoom * 0.85)); + } + + comboSpr.updateHitbox(); + rating.updateHitbox(); + + var seperatedScore:Array = []; + //much faster combo popup stuff + for (i in 0...Std.string(combo).length) { + seperatedScore.push(Std.parseInt(Std.string(combo).split("")[i])); + } + + + + var daLoop:Int = 0; + var xThing:Float = 0; + if (ClientPrefs.comboPopup && !cpuControlled) + { + insert(members.indexOf(strumLineNotes), comboSpr); + } + if (!ClientPrefs.comboStacking) + { + if (lastCombo != null) lastCombo.kill(); + lastCombo = comboSpr; + } + if (lastScore != null) + { + while (lastScore.length > 0) + { + lastScore[0].kill(); + lastScore.remove(lastScore[0]); + } + } + for (i in seperatedScore) + { + var numScore:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2)); + numScore.cameras = (ClientPrefs.wrongCameras ? [camGame] : [camHUD]); + numScore.screenCenter(); + numScore.x = coolText.x + (43 * daLoop) - 90; + numScore.y += 80; + + numScore.x += ClientPrefs.comboOffset[2]; + numScore.y -= ClientPrefs.comboOffset[3]; +if (ClientPrefs.colorRatingHit && ClientPrefs.hudType != 'Tails Gets Trolled V4' && ClientPrefs.hudType != 'Doki Doki+' && noteDiff >= ClientPrefs.marvWindow) numScore.color = rating.color; +if (!allSicks && ClientPrefs.colorRatingFC && marvs > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') + { + numScore.color = tgtJudgeColours.get('marv'); + } +if (!allSicks && ClientPrefs.colorRatingFC && sicks > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') + { + numScore.color = tgtJudgeColours.get('sick'); + } +if (!allSicks && ClientPrefs.colorRatingFC && goods > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') + { + numScore.color = tgtJudgeColours.get('good'); + } +if (!allSicks && ClientPrefs.colorRatingFC && bads > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') + { + numScore.color = tgtJudgeColours.get('bad'); + } +if (!allSicks && ClientPrefs.colorRatingFC && shits > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') + { + numScore.color = tgtJudgeColours.get('shit'); + } +if (!allSicks && ClientPrefs.colorRatingFC && songMisses > 0 && ClientPrefs.hudType != 'Doki Doki+' && ClientPrefs.hudType == 'Tails Gets Trolled V4') + { + numScore.color = FlxColor.WHITE; + } + + if (!ClientPrefs.comboStacking) + lastScore.push(numScore); + + if (!PlayState.isPixelStage) + { + numScore.antialiasing = ClientPrefs.globalAntialiasing; + 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) * playbackRate * playbackRate; + numScore.velocity.y -= FlxG.random.int(140, 160) * playbackRate; + numScore.velocity.x = FlxG.random.float(-5, 5) * playbackRate; + numScore.visible = !ClientPrefs.hideHud; + + //if (combo >= 10 || combo == 0) + if(showComboNum) + insert(members.indexOf(strumLineNotes), numScore); + + FlxTween.tween(numScore, {alpha: 0}, 0.2 / playbackRate, { + onComplete: function(tween:FlxTween) + { + numScore.destroy(); + }, + startDelay: Conductor.crochet * 0.002 / playbackRate + }); + + daLoop++; + if(numScore.x > xThing) xThing = numScore.x; + } + comboSpr.x = xThing + 50; + /* + trace(combo); + trace(seperatedScore); + */ + + coolText.text = Std.string(seperatedScore); + // add(coolText); + + FlxTween.tween(rating, {alpha: 0}, 0.2 / playbackRate, { + startDelay: Conductor.crochet * 0.001 / playbackRate + }); + + FlxTween.tween(comboSpr, {alpha: 0}, 0.2 / playbackRate, { + onComplete: function(tween:FlxTween) + { + coolText.destroy(); + comboSpr.destroy(); + + rating.destroy(); + }, + startDelay: Conductor.crochet * 0.002 / playbackRate + }); + } + } + + public var strumsBlocked:Array = []; + private function onKeyPress(event:KeyboardEvent):Void + { + var eventKey:FlxKey = event.keyCode; + var key:Int = getKeyFromEvent(eventKey); + //trace('Pressed: ' + eventKey); + + if (!cpuControlled && startedCountdown && !paused && key > -1 && !softlocked && (FlxG.keys.checkStatus(eventKey, JUST_PRESSED) || ClientPrefs.controllerMode)) + { + if(!boyfriend.stunned && generatedMusic && !endingSong) + { + //more accurate hit time for the ratings? + var lastTime:Float = Conductor.songPosition; + if (ClientPrefs.songLoading) Conductor.songPosition = FlxG.sound.music.time; + + var canMiss:Bool = !ClientPrefs.ghostTapping; + + // heavily based on my own code LOL if it aint broke dont fix it + var pressNotes:Array = []; + //var notesDatas:Array = []; + var notesStopped:Bool = false; + + var hittableSpam = []; + + var sortedNotesList:Array = []; + notes.forEachAlive(function(daNote:Note) + { + if (strumsBlocked[daNote.noteData] != true && daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit && !daNote.isSustainNote && !daNote.blockHit) + { + if(daNote.noteData == key) + { + sortedNotesList.push(daNote); + //notesDatas.push(daNote.noteData); + } + canMiss = true; + } + }); + sortedNotesList.sort(sortHitNotes); + + if (sortedNotesList.length > 0) { + for (epicNote in sortedNotesList) + { + for (doubleNote in pressNotes) { + if (Math.abs(doubleNote.strumTime - epicNote.strumTime) < 1) { + if (shouldKillNotes) + { + doubleNote.kill(); + } + notes.remove(doubleNote, true); + if (shouldKillNotes) + { + doubleNote.destroy(); + } + } else + notesStopped = true; + } + + // eee jack detection before was not super good + if (!notesStopped) { + goodNoteHit(epicNote); + pressNotes.push(epicNote); + } + if (sortedNotesList.length > 2 && ClientPrefs.ezSpam) //literally all you need to allow you to spam though impossiblely hard jacks + { + var notesThatCanBeHit = sortedNotesList.length; + for (i in 1...Std.int(notesThatCanBeHit)) //i may consider making this hit half the notes instead + { + goodNoteHit(sortedNotesList[i]); + } + + } + } + } + else { + callOnLuas('onGhostTap', [key]); + if (!opponentChart && ClientPrefs.ghostTapAnim && ClientPrefs.charsAndBG) + { + boyfriend.playAnim(singAnimations[Std.int(Math.abs(key))], true); + if (ClientPrefs.cameraPanning) camPanRoutine(singAnimations[Std.int(Math.abs(key))], 'bf'); + boyfriend.holdTimer = 0; + } + if (opponentChart && ClientPrefs.ghostTapAnim && ClientPrefs.charsAndBG) + { + dad.playAnim(singAnimations[Std.int(Math.abs(key))], true); + if (ClientPrefs.cameraPanning) camPanRoutine(singAnimations[Std.int(Math.abs(key))], 'dad'); + dad.holdTimer = 0; + } + if (canMiss) { + noteMissPress(key); + } + } + + // I dunno what you need this for but here you go + // - Shubs + + // Shubs, this is for the "Just the Two of Us" achievement lol + // - Shadow Mario + keysPressed[key] = true; + + //more accurate hit time for the ratings? part 2 (Now that the calculations are done, go back to the time it was before for not causing a note stutter) + Conductor.songPosition = lastTime; + } + + var spr:StrumNote = playerStrums.members[key]; + if(strumsBlocked[key] != true && spr != null && spr.animation.curAnim.name != 'confirm') + { + spr.playAnim('pressed'); + spr.resetAnim = 0; + } + callOnLuas('onKeyPress', [key]); + } + //trace('pressed: ' + controlArray); + } + + function sortHitNotes(a:Note, b:Note):Int + { + if (a.lowPriority && !b.lowPriority) + return 1; + else if (!a.lowPriority && b.lowPriority) + return -1; + + return FlxSort.byValues(FlxSort.ASCENDING, a.strumTime, b.strumTime); + } + + private function onKeyRelease(event:KeyboardEvent):Void + { + var eventKey:FlxKey = event.keyCode; + var key:Int = getKeyFromEvent(eventKey); + if(!cpuControlled && startedCountdown && !paused && key > -1) + { + var spr:StrumNote = playerStrums.members[key]; + if(spr != null) + { + spr.playAnim('static'); + spr.resetAnim = 0; + } + callOnLuas('onKeyRelease', [key]); + } + //trace('released: ' + controlArray); + } + + private function getKeyFromEvent(key:FlxKey):Int + { + if(key != NONE) + { + for (i in 0...keysArray.length) + { + for (j in 0...keysArray[i].length) + { + if(key == keysArray[i][j]) + { + return i; + } + } + } + } + return -1; + } + + // Hold notes + private function keyShit():Void + { + // HOLDING + var parsedHoldArray:Array = parseKeys(); + + // TO DO: Find a better way to handle controller inputs, this should work for now + if(ClientPrefs.controllerMode) + { + var parsedArray:Array = parseKeys('_P'); + if(parsedArray.contains(true)) + { + for (i in 0...parsedArray.length) + { + if(parsedArray[i] && strumsBlocked[i] != true) + onKeyPress(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, true, -1, keysArray[i][0])); + } + } + } + + // FlxG.watch.addQuick('asdfa', upP); + var char:Character = boyfriend; + if (opponentChart) char = dad; + if (startedCountdown && !char.stunned && generatedMusic) + { + // rewritten inputs??? + notes.forEachAlive(function(daNote:Note) + { + // hold note functions + if (strumsBlocked[daNote.noteData] != true && daNote.isSustainNote && parsedHoldArray[daNote.noteData] && daNote.canBeHit + && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit && !daNote.blockHit) { + goodNoteHit(daNote); + } + }); + + if(ClientPrefs.charsAndBG && FlxG.keys.anyJustPressed(tauntKey) && !char.animation.curAnim.name.endsWith('miss') && char.specialAnim == false && ClientPrefs.spaceVPose){ + char.playAnim('hey', true); + char.specialAnim = true; + char.heyTimer = 0.59; + FlxG.sound.play(Paths.sound('hey')); + trace("HEY!!"); + } + + if (parsedHoldArray.contains(true) && !endingSong) { + #if ACHIEVEMENTS_ALLOWED + var achieve:String = checkForAchievement(['oversinging']); + if (achieve != null) { + startAchievement(achieve); + } + #end + } + else if (ClientPrefs.charsAndBG && boyfriend.animation.curAnim != null && boyfriend.holdTimer > Conductor.stepCrochet * (0.0011 / playbackRate) * boyfriend.singDuration && boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss')) + { + boyfriend.dance(); + //boyfriend.animation.curAnim.finish(); + } + else if (ClientPrefs.charsAndBG && dad.holdTimer > Conductor.stepCrochet * (0.0011 / playbackRate) * dad.singDuration + && dad.animation.curAnim.name.startsWith('sing') && !dad.animation.curAnim.name.endsWith('miss')) { + dad.dance(); + } + } + + // TO DO: Find a better way to handle controller inputs, this should work for now + if(ClientPrefs.controllerMode || strumsBlocked.contains(true)) + { + var parsedArray:Array = parseKeys('_R'); + if(parsedArray.contains(true)) + { + for (i in 0...parsedArray.length) + { + if(parsedArray[i] || strumsBlocked[i] == true) + onKeyRelease(new KeyboardEvent(KeyboardEvent.KEY_UP, true, true, -1, keysArray[i][0])); + } + } + } + } + + private function parseKeys(?suffix:String = ''):Array + { + var ret:Array = []; + for (i in 0...controlArray.length) + { + ret[i] = Reflect.getProperty(controls, controlArray[i] + suffix); + } + return ret; + } + + function noteMiss(daNote:Note):Void { //You didn't hit the key and let it go offscreen, also used by Hurt Notes + //Dupe note remove + notes.forEachAlive(function(note:Note) { + if (daNote != note && daNote.mustPress && daNote.noteData == note.noteData && daNote.isSustainNote == note.isSustainNote && Math.abs(daNote.strumTime - note.strumTime) < 1) { + if (shouldKillNotes) + { + note.kill(); + } + notes.remove(note, true); + if (shouldKillNotes) + { + note.destroy(); + } + } + }); + combo = 0; + comboMultiplier = 1; // Reset to 1 on a miss + if (ClientPrefs.healthGainType == 'Psych Engine') { + health -= daNote.missHealth * healthLoss; + } + if (ClientPrefs.healthGainType == 'Kade (1.2)') { + health -= daNote.missHealth * healthLoss; + } + if (ClientPrefs.healthGainType == 'Leather Engine') { + health -= 0.07 * healthLoss; + } + if (ClientPrefs.healthGainType == 'Kade (1.4.2 to 1.6)') { + health -= 0.075 * healthLoss; + } + if (ClientPrefs.healthGainType == 'Kade (1.6+)') { + health -= 0.1 * healthLoss; + } + if (ClientPrefs.healthGainType == 'Doki Doki+') { + health -= 0.04 * healthLoss; + } + if (ClientPrefs.healthGainType == 'VS Impostor') { + missCombo += 1; + health -= daNote.missHealth * missCombo; + } + + + if(instakillOnMiss) + { + vocals.volume = 0; + doDeathCheck(true); + } + + //For testing purposes + //trace(daNote.missHealth); + songMisses++; + vocals.volume = 0; + if(!practiceMode) songScore -= 10 * Std.int(polyphony); + + totalPlayed++; + RecalculateRating(true); + + var char:Character = boyfriend; + if(daNote.gfNote) { + char = gf; + } + if (opponentChart) char = dad; + + if(char != null && !daNote.noMissAnimation && char.hasMissAnimations && ClientPrefs.charsAndBG) + { + var animToPlay:String = singAnimations[Std.int(Math.abs(daNote.noteData))] + 'miss' + daNote.animSuffix; + char.playAnim(animToPlay, true); + } + + callOnLuas('noteMiss', [notes.members.indexOf(daNote), daNote.noteData, daNote.noteType, daNote.isSustainNote]); + } + + function noteMissPress(direction:Int = 1):Void //You pressed a key when there was no notes to press for this key + { + if(ClientPrefs.ghostTapping) return; //fuck it + + if (!boyfriend.stunned) + { + + health -= 0.05 * healthLoss; + if(instakillOnMiss) + { + vocals.volume = 0; + doDeathCheck(true); + } + + if (combo > 5 && gf != null && gf.animOffsets.exists('sad')) + { + gf.playAnim('sad'); + } + combo = 0; + comboMultiplier = 1; // Reset to 1 on a miss + + if(!practiceMode) songScore -= 10; + if(!endingSong) { + songMisses++; + } + totalPlayed++; + RecalculateRating(true); + + FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); + // FlxG.sound.play(Paths.sound('missnote1'), 1, false); + // FlxG.log.add('played imss note'); + + /*boyfriend.stunned = true; + + // get stunned for 1/60 of a second, makes you able to + new FlxTimer().start(1 / 60, function(tmr:FlxTimer) + { + boyfriend.stunned = false; + });*/ + + var char:Character = boyfriend; + if (opponentChart) char = dad; + if(char.hasMissAnimations) { + char.playAnim(singAnimations[Std.int(Math.abs(direction))] + 'miss', true); + } + vocals.volume = 0; + } + callOnLuas('noteMissPress', [direction]); + } + + var hitsound:FlxSound; + var hitsound2:FlxSound; + var hitsound3:FlxSound; + var hitsound4:FlxSound; + var hitsound5:FlxSound; + var hitsound6:FlxSound; + var hitsound7:FlxSound; + var hitsound8:FlxSound; + var hitsound9:FlxSound; + var hitsound10:FlxSound; + var hitsound11:FlxSound; + + function goodNoteHit(note:Note):Void + { + if (opponentChart) { + if (Paths.formatToSongPath(SONG.song) != 'tutorial' && !camZooming) + camZooming = true; + } + if (!note.wasGoodHit) + { + if(cpuControlled && (note.ignoreNote || note.hitCausesMiss)) return; + + if (ClientPrefs.hitsoundVolume > 0 && !note.hitsoundDisabled) + { + if (hitSoundString != 'Randomized') + { + hitsound.play(true); + hitsound.pitch = playbackRate; + } + if (hitSoundString == 'Randomized') + { + hitsound.pitch = playbackRate; + hitsound2.pitch = playbackRate; + hitsound3.pitch = playbackRate; + hitsound4.pitch = playbackRate; + hitsound5.pitch = playbackRate; + hitsound6.pitch = playbackRate; + hitsound7.pitch = playbackRate; + hitsound8.pitch = playbackRate; + hitsound9.pitch = playbackRate; + hitsound10.pitch = playbackRate; + hitsound11.pitch = playbackRate; + } + if (hitSoundString == 'vine boom') + { + SPUNCHBOB = new FlxSprite().loadGraphic(Paths.image('sadsponge')); + SPUNCHBOB.antialiasing = ClientPrefs.globalAntialiasing; + SPUNCHBOB.scrollFactor.set(); + SPUNCHBOB.setGraphicSize(Std.int(SPUNCHBOB.width / FlxG.camera.zoom)); + SPUNCHBOB.updateHitbox(); + SPUNCHBOB.screenCenter(); + SPUNCHBOB.alpha = 1; + SPUNCHBOB.cameras = [camGame]; + add(SPUNCHBOB); + FlxTween.tween(SPUNCHBOB, {alpha: 0}, 1 / (SONG.bpm/100) / playbackRate, { + onComplete: function(tween:FlxTween) + { + SPUNCHBOB.destroy(); + } + }); + } + if (hitSoundString == "i'm spongebob!") + { + SPUNCHBOB = new FlxSprite().loadGraphic(Paths.image('itspongebob')); + SPUNCHBOB.antialiasing = ClientPrefs.globalAntialiasing; + SPUNCHBOB.scrollFactor.set(); + SPUNCHBOB.setGraphicSize(Std.int(SPUNCHBOB.width / FlxG.camera.zoom)); + SPUNCHBOB.updateHitbox(); + SPUNCHBOB.screenCenter(); + SPUNCHBOB.alpha = 1; + SPUNCHBOB.cameras = [camGame]; + add(SPUNCHBOB); + FlxTween.tween(SPUNCHBOB, {alpha: 0}, 1 / (SONG.bpm/100) / playbackRate, { + onComplete: function(tween:FlxTween) + { + SPUNCHBOB.destroy(); + } + }); + } + if (ClientPrefs.hitsoundType == 'Randomized') { + var randomHitSoundType:Int = FlxG.random.int(1, 11); + switch (randomHitSoundType) + { + case 1: + hitsound.play(true); + hitsound.pitch = playbackRate; + case 2: + hitsound2.play(true); + hitsound2.pitch = playbackRate; + case 3: + hitsound3.play(true); + hitsound3.pitch = playbackRate; + case 4: + hitsound4.play(true); + hitsound4.pitch = playbackRate; + case 5: + hitsound5.play(true); + hitsound5.pitch = playbackRate; + case 6: + hitsound6.play(true); + hitsound6.pitch = playbackRate; + case 7: + hitsound7.play(true); + hitsound7.pitch = playbackRate; + case 8: + hitsound8.play(true); + hitsound8.pitch = playbackRate; + { + SPUNCHBOB = new FlxSprite().loadGraphic(Paths.image('sadsponge')); + SPUNCHBOB.antialiasing = ClientPrefs.globalAntialiasing; + SPUNCHBOB.scrollFactor.set(); + SPUNCHBOB.setGraphicSize(Std.int(SPUNCHBOB.width / FlxG.camera.zoom)); + SPUNCHBOB.updateHitbox(); + SPUNCHBOB.screenCenter(); + SPUNCHBOB.alpha = 1; + SPUNCHBOB.cameras = [camGame]; + add(SPUNCHBOB); + FlxTween.tween(SPUNCHBOB, {alpha: 0}, 1 / (SONG.bpm/100) / playbackRate, { + onComplete: function(tween:FlxTween) + { + SPUNCHBOB.destroy(); + } + }); + } + case 9: + hitsound9.play(true); + hitsound9.pitch = playbackRate; + case 10: + hitsound10.play(true); + hitsound10.pitch = playbackRate; + case 11: + hitsound11.play(true); + hitsound11.pitch = playbackRate; + { + SPUNCHBOB = new FlxSprite().loadGraphic(Paths.image('itspongebob')); + SPUNCHBOB.antialiasing = ClientPrefs.globalAntialiasing; + SPUNCHBOB.scrollFactor.set(); + SPUNCHBOB.setGraphicSize(Std.int(SPUNCHBOB.width / FlxG.camera.zoom)); + SPUNCHBOB.updateHitbox(); + SPUNCHBOB.screenCenter(); + SPUNCHBOB.alpha = 1; + SPUNCHBOB.cameras = [camGame]; + add(SPUNCHBOB); + FlxTween.tween(SPUNCHBOB, {alpha: 0}, 1 / (SONG.bpm/100) / playbackRate, { + onComplete: function(tween:FlxTween) + { + SPUNCHBOB.destroy(); + } + }); + } + } + } + } + + if(note.hitCausesMiss) { + noteMiss(note); + if(!note.noteSplashDisabled && !note.isSustainNote) { + spawnNoteSplashOnNote(false, note); + } + + if(!note.noMissAnimation) + { + switch(note.noteType) { + case 'Hurt Note': //Hurt note + if(boyfriend.animation.getByName('hurt') != null) { + boyfriend.playAnim('hurt', true); + boyfriend.specialAnim = true; + } + } + } + + note.wasGoodHit = true; + if (!note.isSustainNote) + { + if (shouldKillNotes) + { + note.kill(); + } + if (ClientPrefs.showNotes) notes.remove(note, true); + if (shouldKillNotes) + { + note.destroy(); + } + } + return; + } + if (ClientPrefs.comboScoreEffect && ClientPrefs.comboMultiType == 'Voiid Chronicles') + { + comboMultiplier = Math.fceil((combo+1)/10); + } + + if (!note.isSustainNote && !cpuControlled && !ClientPrefs.lessBotLag || !note.isSustainNote && cpuControlled && ClientPrefs.communityGameBot) + { + combo += 1 * polyphony; + totalNotesPlayed += 1 * polyphony; + missCombo = 0; + if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well + notesHitArray.push(1 * polyphony); + notesHitDateArray.push(Date.now()); + } + popUpScore(note); + } + if (note.isSustainNote && !cpuControlled && ClientPrefs.holdNoteHits) + { + combo += 1 * polyphony; + totalNotesPlayed += 1 * polyphony; + missCombo = 0; + popUpScore(note); + } + if (note.isSustainNote && cpuControlled && ClientPrefs.communityGameBot && ClientPrefs.holdNoteHits && !ClientPrefs.lessBotLag) + { + combo += 1 * polyphony; + totalNotesPlayed += 1 * polyphony; + missCombo = 0; + popUpScore(note); + } + if (note.isSustainNote && cpuControlled && ClientPrefs.holdNoteHits && ClientPrefs.lessBotLag) + { + combo += 1 * polyphony; + totalNotesPlayed += 1 * polyphony; + if (!ClientPrefs.noMarvJudge) + { + songScore += 500 * comboMultiplier * polyphony; + } + else if (ClientPrefs.noMarvJudge) + { + songScore += 350 * comboMultiplier * polyphony; + } + missCombo = 0; + } + if (!note.isSustainNote && cpuControlled && ClientPrefs.lessBotLag && !ClientPrefs.communityGameBot) + { + if (!ClientPrefs.noMarvJudge) + { + songScore += 500 * comboMultiplier * polyphony; + } + else if (ClientPrefs.noMarvJudge) + { + songScore += 350 * comboMultiplier * polyphony; + } + combo += 1 * polyphony; + totalNotesPlayed += 1 * polyphony; + if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well + notesHitArray.push(1 * polyphony); + notesHitDateArray.push(Date.now()); + } + if(!note.noteSplashDisabled && !note.isSustainNote) { + spawnNoteSplashOnNote(false, note); + } + } + if (!note.isSustainNote && cpuControlled && !ClientPrefs.lessBotLag && !ClientPrefs.communityGameBot) + { + combo += 1 * polyphony; + totalNotesPlayed += 1 * polyphony; + //updateScore(); the update function handles updating this, so why make it update more + //updateRatingCounter(); the update function handles updating this, so why make it update more + missCombo = 0; + if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well + notesHitArray.push(1 * polyphony); + notesHitDateArray.push(Date.now()); + } + popUpScore(note); + } + if (!note.isSustainNote && !cpuControlled && ClientPrefs.lessBotLag && !ClientPrefs.communityGameBot) + { + combo += 1 * polyphony; + totalNotesPlayed += 1 * polyphony; + //updateScore(); the update function handles updating this, so why make it update more + //updateRatingCounter(); the update function handles updating this, so why make it update more + missCombo = 0; + if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well + notesHitArray.push(1 * polyphony); + notesHitDateArray.push(Date.now()); + } + var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition + ClientPrefs.ratingOffset); + var daRating:Rating = Conductor.judgeNote(note, noteDiff / playbackRate); + + totalNotesHit += daRating.ratingMod; + //if (ClientPrefs.complexAccuracy) totalNotesHit += wife; whoopsies + note.ratingMod = daRating.ratingMod; + if(!note.ratingDisabled) daRating.increase(); + note.rating = daRating.name; + songScore += daRating.score * comboMultiplier * polyphony; + totalPlayed++; + if(daRating.noteSplash && !note.noteSplashDisabled) + { + spawnNoteSplashOnNote(false, note); + } + RecalculateRating(); + } + if (note.isSustainNote && cpuControlled && !ClientPrefs.lessBotLag && !ClientPrefs.communityGameBot && ClientPrefs.holdNoteHits) + { + combo += 1 * polyphony; + totalNotesPlayed += 1 * polyphony; + //updateScore(); the update function handles updating this, so why make it update more + //updateRatingCounter(); the update function handles updating this, so why make it update more + missCombo = 0; + if (ClientPrefs.showNPS) { //i dont think we should be pushing to 2 arrays at the same time but oh well + notesHitArray.push(1 * polyphony); + notesHitDateArray.push(Date.now()); + } + popUpScore(note); + } + if (ClientPrefs.healthGainType == 'Psych Engine') { + health += note.hitHealth * healthGain * polyphony; + } + if (ClientPrefs.healthGainType == 'Leather Engine') { + health += note.hitHealth * healthGain * polyphony; + } + if (ClientPrefs.healthGainType == 'Kade (1.2)') { + health += note.hitHealth * healthGain * polyphony; + } + if (ClientPrefs.healthGainType == 'Kade (1.6+)') { + health += note.hitHealth * healthGain * polyphony; + } + if (ClientPrefs.healthGainType == 'Doki Doki+') { + health += note.hitHealth * healthGain * polyphony; + } + if (ClientPrefs.healthGainType == 'VS Impostor') { + health += note.hitHealth * healthGain * polyphony; + } + if(!note.noAnimation && ClientPrefs.charsAndBG) { + var animToPlay:String = singAnimations[Std.int(Math.abs(note.noteData))]; + + var char:Character = boyfriend; + if(opponentChart) char = dad; + if(note.gfNote) + { + if(gf != null) + { + if (!ClientPrefs.doubleGhost) { + gf.playAnim(animToPlay + note.animSuffix, true); + } + gf.holdTimer = 0; + if (ClientPrefs.doubleGhost) + { + if (!note.isSustainNote && noteRows[note.mustPress?0:1][note.row].length > 1) + { + // potentially have jump anims? + var chord = noteRows[note.mustPress?0:1][note.row]; + var animNote = chord[0]; + var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; + if (gf.mostRecentRow != note.row) + { + gf.playAnim(realAnim, true); + } + + // if (daNote != animNote) + // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); + + + gf.mostRecentRow = note.row; + // dad.angle += 15; lmaooooo + doGhostAnim('gf', animToPlay); + gfGhost.color = FlxColor.fromRGB(gf.healthColorArray[0] + 50, gf.healthColorArray[1] + 50, gf.healthColorArray[2] + 50); + gfGhostTween = FlxTween.tween(gfGhost, {alpha: 0}, 0.75, { + ease: FlxEase.linear, + onComplete: function(twn:FlxTween) + { + gfGhostTween = null; + } + }); + } + else{ + gf.playAnim(animToPlay + note.animSuffix, true); + // dad.angle = 0; + } + } + } + } + if (!opponentChart && !note.gfNote && ClientPrefs.charsAndBG) + { + if (!ClientPrefs.doubleGhost) { + boyfriend.playAnim(animToPlay + note.animSuffix, true); + } + if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'bf'); + boyfriend.holdTimer = 0; + if (ClientPrefs.doubleGhost) + { + if (!note.isSustainNote && noteRows[note.mustPress?0:1][note.row].length > 1) + { + // potentially have jump anims? + var chord = noteRows[note.mustPress?0:1][note.row]; + var animNote = chord[0]; + var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; + if (boyfriend.mostRecentRow != note.row) + { + boyfriend.playAnim(realAnim, true); + } + + // if (daNote != animNote) + // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); + + boyfriend.mostRecentRow = note.row; + // dad.angle += 15; lmaooooo + doGhostAnim('bf', animToPlay); + } + else{ + boyfriend.playAnim(animToPlay + note.animSuffix, true); + // dad.angle = 0; + } + } + } + if (opponentChart && !note.gfNote && ClientPrefs.charsAndBG) + { + if (!ClientPrefs.doubleGhost) { + dad.playAnim(animToPlay, true); + } + dad.holdTimer = 0; + if (ClientPrefs.cameraPanning) camPanRoutine(animToPlay, 'oppt'); + if (ClientPrefs.doubleGhost) + { + if (!note.isSustainNote && noteRows[note.mustPress?0:1][note.row].length > 1) + { + // potentially have jump anims? + var chord = noteRows[note.mustPress?0:1][note.row]; + var animNote = chord[0]; + var realAnim = singAnimations[Std.int(Math.abs(animNote.noteData))]; + if (dad.mostRecentRow != note.row) + { + dad.playAnim(realAnim, true); + } + + // if (daNote != animNote) + // dad.playGhostAnim(chord.indexOf(daNote)-1, animToPlay, true); + + // dad.angle += 15; lmaooooo + if (!note.noAnimation && !note.gfNote) + { + if(dad.mostRecentRow != note.row) + doGhostAnim('dad', animToPlay); + dadGhost.color = FlxColor.fromRGB(dad.healthColorArray[0] + 50, dad.healthColorArray[1] + 50, dad.healthColorArray[2] + 50); + dadGhostTween = FlxTween.tween(dadGhost, {alpha: 0}, 0.75, { + ease: FlxEase.linear, + onComplete: function(twn:FlxTween) + { + dadGhostTween = null; + } + }); + } + dad.mostRecentRow = note.row; + } + else{ + dad.playAnim(animToPlay + note.animSuffix, true); + // dad.angle = 0; + } + } + } + + if(note.noteType == 'Hey!') { + if(char.animOffsets.exists('hey')) { + char.playAnim('hey', true); + char.specialAnim = true; + char.heyTimer = 0.6; + } + + if(gf != null && gf.animOffsets.exists('cheer')) { + gf.playAnim('cheer', true); + gf.specialAnim = true; + gf.heyTimer = 0.6; + } + } + } + + if (ClientPrefs.ratingCounter && judgeCountUpdateFrame == 0) updateRatingCounter(); + if (!ClientPrefs.hideScore && scoreTxtUpdateFrame == 0) updateScore(); + if (ClientPrefs.compactNumbers && compactUpdateFrame == 0) updateCompactNumbers(); + + if(cpuControlled) { + if (ClientPrefs.botLightStrum) + { + var time:Float = (!ClientPrefs.communityGameBot ? 0.15 : FlxG.random.float(0.05, 0.15)) / playbackRate; + if(note.isSustainNote && (ClientPrefs.showNotes && !note.animation.curAnim.name.endsWith('end'))) { + time += (!ClientPrefs.communityGameBot ? 0.15 : FlxG.random.float(0.05, 0.15)) / playbackRate; + } + var spr:StrumNote = playerStrums.members[note.noteData]; + + if(spr != null) { + if ((ClientPrefs.colorQuants || ClientPrefs.rainbowNotes) && ClientPrefs.showNotes) { + spr.playAnim('confirm', true, note.colorSwap.hue, note.colorSwap.saturation, note.colorSwap.brightness); + } else { + spr.playAnim('confirm', true); + } + spr.resetAnim = time; + } + } + } else if (ClientPrefs.playerLightStrum) { + var spr = playerStrums.members[note.noteData]; + if(spr != null) + { + if ((ClientPrefs.colorQuants || ClientPrefs.rainbowNotes) && ClientPrefs.showNotes) { + spr.playAnim('confirm', true, note.colorSwap.hue, note.colorSwap.saturation, note.colorSwap.brightness); + } else { + spr.playAnim('confirm', true); + } + } + } + note.wasGoodHit = true; + if (ClientPrefs.songLoading) vocals.volume = 1; + + var isSus:Bool = note.isSustainNote; //GET OUT OF MY HEAD, GET OUT OF MY HEAD, GET OUT OF MY HEAD + var leData:Int = Math.round(Math.abs(note.noteData)); + var leType:String = note.noteType; + + callOnLuas('goodNoteHit', [notes.members.indexOf(note), Math.abs(note.noteData), note.noteType, note.isSustainNote]); + callOnLuas((opponentChart ? 'opponentNoteHitFix' : 'goodNoteHitFix'), [notes.members.indexOf(note), leData, leType, isSus]); + + if (!note.isSustainNote) + { + if (shouldKillNotes) + { + note.kill(); + } + notes.remove(note, true); + if (shouldKillNotes) + { + note.destroy(); + } + } + } + } + + public function spawnNoteSplashOnNote(isDad:Bool, note:Note) { + if(ClientPrefs.noteSplashes && note != null) { + var strum:StrumNote = playerStrums.members[note.noteData]; + if (isDad) { + strum = opponentStrums.members[note.noteData]; + } else { + strum = playerStrums.members[note.noteData]; + } + if(strum != null) { + spawnNoteSplash(strum.x, strum.y, note.noteData); + } + } + } + + public function spawnNoteSplash(x:Float, y:Float, data:Int, ?note:Note = null) { + var skin:String = 'noteSplashes'; + if(PlayState.SONG.splashSkin != null && PlayState.SONG.splashSkin.length > 0) skin = PlayState.SONG.splashSkin; + //if (ClientPrefs.splashType == 'VS Impostor') PlayState.SONG.splashSkin = 'impostorNoteSplashes'; + //if (ClientPrefs.splashType == 'Tails Gets Trolled V4') PlayState.SONG.splashSkin = 'tgtNoteSplashes'; + + var hue:Float = 0; + var sat:Float = 0; + var brt:Float = 0; + if (data > -1 && data < ClientPrefs.arrowHSV.length) + { + hue = ClientPrefs.arrowHSV[data][0] / 360; + sat = ClientPrefs.arrowHSV[data][1] / 100; + brt = ClientPrefs.arrowHSV[data][2] / 100; + if(note != null) { + skin = note.noteSplashTexture; + hue = note.noteSplashHue; + sat = note.noteSplashSat; + brt = note.noteSplashBrt; + } + } + + var splash:NoteSplash = grpNoteSplashes.recycle(NoteSplash); + splash.setupNoteSplash(x, y, data, skin, hue, sat, brt); + grpNoteSplashes.add(splash); + } + + var fastCarCanDrive:Bool = true; + + function resetFastCar():Void + { + fastCar.x = -12600; + fastCar.y = FlxG.random.int(140, 250); + fastCar.velocity.x = 0; + fastCarCanDrive = true; + } + + var carTimer:FlxTimer; + function fastCarDrive() + { + //trace('Car drive'); + FlxG.sound.play(Paths.soundRandom('carPass', 0, 1), 0.7); + + fastCar.velocity.x = (FlxG.random.int(170, 220) / FlxG.elapsed) * 3; + fastCarCanDrive = false; + carTimer = new FlxTimer().start(2, function(tmr:FlxTimer) + { + resetFastCar(); + carTimer = null; + }); + } + + var trainMoving:Bool = false; + var trainFrameTiming:Float = 0; + + var trainCars:Int = 8; + var trainFinishing:Bool = false; + var trainCooldown:Int = 0; + + function trainStart():Void + { + trainMoving = true; + if (!trainSound.playing) + trainSound.play(true); + } + + var startedMoving:Bool = false; + + function updateTrainPos():Void + { + if (trainSound.time >= 4700) + { + startedMoving = true; + if (gf != null) + { + gf.playAnim('hairBlow'); + gf.specialAnim = true; + } + } + + 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(gf != null) + { + gf.danced = false; //Sets head to the correct position once the animation ends + gf.playAnim('hairFall'); + gf.specialAnim = true; + } + 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)); + if(!ClientPrefs.lowQuality) halloweenBG.animation.play('halloweem bg lightning strike'); + + lightningStrikeBeat = curBeat; + lightningOffset = FlxG.random.int(8, 24); + + if(boyfriend.animOffsets.exists('scared')) { + boyfriend.playAnim('scared', true); + } + + if(gf != null && gf.animOffsets.exists('scared')) { + gf.playAnim('scared', true); + } + + if(ClientPrefs.camZooms) { + FlxG.camera.zoom += 0.015; + camHUD.zoom += 0.03; + + if(!camZooming) { //Just a way for preventing it to be permanently zoomed until Skid & Pump hits a note + FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom}, 0.5); + FlxTween.tween(camHUD, {zoom: 1}, 0.5); + } + } + + if(ClientPrefs.flashing) { + halloweenWhite.alpha = 0.4; + FlxTween.tween(halloweenWhite, {alpha: 0.5}, 0.075); + FlxTween.tween(halloweenWhite, {alpha: 0}, 0.25, {startDelay: 0.15}); + } + } + + function killHenchmen():Void + { + if(!ClientPrefs.lowQuality && ClientPrefs.violence && curStage == 'limo') { + if(limoKillingState < 1) { + limoMetalPole.x = -400; + limoMetalPole.visible = true; + limoLight.visible = true; + limoCorpse.visible = false; + limoCorpseTwo.visible = false; + limoKillingState = 1; + + #if ACHIEVEMENTS_ALLOWED + Achievements.henchmenDeath++; + FlxG.save.data.henchmenDeath = Achievements.henchmenDeath; + var achieve:String = checkForAchievement(['roadkill_enthusiast']); + if (achieve != null) { + startAchievement(achieve); + } else { + FlxG.save.flush(); + } + FlxG.log.add('Deaths: ' + Achievements.henchmenDeath); + #end + } + } + } + + function resetLimoKill():Void + { + if(curStage == 'limo') { + limoMetalPole.x = -500; + limoMetalPole.visible = false; + limoLight.x = -500; + limoLight.visible = false; + limoCorpse.x = -500; + limoCorpse.visible = false; + limoCorpseTwo.x = -500; + limoCorpseTwo.visible = false; + } + } + + var tankX:Float = 400; + var tankSpeed:Float = FlxG.random.float(5, 7); + var tankAngle:Float = FlxG.random.int(-90, 45); + + function moveTank(?elapsed:Float = 0):Void + { + if(!inCutscene) + { + tankAngle += elapsed * tankSpeed; + tankGround.angle = tankAngle - 90 + 15; + tankGround.x = tankX + 1500 * Math.cos(Math.PI / 180 * (1 * tankAngle + 180)); + tankGround.y = 1300 + 1100 * Math.sin(Math.PI / 180 * (1 * tankAngle + 180)); + } + } + + override function destroy() { + for (lua in luaArray) { + lua.call('onDestroy', []); + lua.stop(); + } + luaArray = []; + + #if hscript + if(FunkinLua.hscript != null) FunkinLua.hscript = null; + #end + + if(!ClientPrefs.controllerMode) + { + FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyPress); + FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, onKeyRelease); + } + FlxAnimationController.globalSpeed = 1; + FlxG.sound.music.pitch = 1; + cpp.vm.Gc.enable(true); + KillNotes(); + super.destroy(); + } + + public static function cancelMusicFadeTween() { + if(FlxG.sound.music.fadeTween != null) { + FlxG.sound.music.fadeTween.cancel(); + } + FlxG.sound.music.fadeTween = null; + } + + var lastStepHit:Int = -1; + override function stepHit() + { + super.stepHit(); + + if (tankmanAscend) + { + if (curStep >= 896 && curStep <= 1152) moveCameraSection(); + switch (curStep) + { + case 896: + { + if (!opponentChart) { + opponentStrums.forEachAlive(function(daNote:FlxSprite) + { + FlxTween.tween(daNote, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + }); + } + FlxTween.tween(EngineWatermark, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(timeBar, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(judgementCounter, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(scoreTxt, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(healthBar, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(healthBarBG, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(iconP1, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(iconP2, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(timeTxt, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + dad.velocity.y = -35; + } + case 906: + { + if (!opponentChart) { + playerStrums.forEachAlive(function(daNote:FlxSprite) + { + FlxTween.tween(daNote, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + }); + } else { + opponentStrums.forEachAlive(function(daNote:FlxSprite) + { + FlxTween.tween(daNote, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + }); + } + } + case 1020: + { + if (!opponentChart) { + playerStrums.forEachAlive(function(daNote:FlxSprite) + { + FlxTween.tween(daNote, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + }); + } + } + case 1024: + if (opponentChart) { + playerStrums.forEachAlive(function(daNote:FlxSprite) + { + FlxTween.tween(daNote, {alpha: 0}, 0.5, {ease: FlxEase.expoOut,}); + }); + } + dad.velocity.y = 0; + boyfriend.velocity.y = -33.5; + case 1148: + { + if (opponentChart) { + playerStrums.forEachAlive(function(daNote:FlxSprite) + { + FlxTween.tween(daNote, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + }); + } + } + case 1151: + cameraSpeed = 100; + case 1152: + { + FlxG.camera.flash(FlxColor.WHITE, 1); + opponentStrums.forEachAlive(function(daNote:FlxSprite) + { + FlxTween.tween(daNote, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + }); + FlxTween.tween(EngineWatermark, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(timeBar, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(judgementCounter, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(healthBar, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(healthBarBG, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(scoreTxt, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(iconP1, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(iconP2, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + FlxTween.tween(timeTxt, {alpha: 1}, 0.5, {ease: FlxEase.expoOut,}); + dad.x = 100; + dad.y = 280; + boyfriend.x = 810; + boyfriend.y = 450; + dad.velocity.y = 0; + boyfriend.velocity.y = 0; + } + case 1153: + cameraSpeed = 1; + } + } + var gamerValue = 20 * playbackRate; + if (!ClientPrefs.noSyncing && ClientPrefs.songLoading && playbackRate < 256) //much better resync code, doesn't just resync every step!! + { + if (FlxG.sound.music.time > Conductor.songPosition + gamerValue + || FlxG.sound.music.time < Conductor.songPosition - gamerValue + || FlxG.sound.music.time < 500 && ClientPrefs.startingSync) + { + resyncVocals(); + } + } + + if(curStep == lastStepHit) { + return; + } + + lastStepHit = curStep; + setOnLuas('curStep', curStep); + callOnLuas('onStepHit', []); + } + + var lightningStrikeBeat:Int = 0; + var lightningOffset:Int = 8; + + var lastBeatHit:Int = -1; + + override function beatHit() + { + super.beatHit(); + + if(ClientPrefs.timeBounce) + { + if(timeTxtTween != null) { + timeTxtTween.cancel(); + } + timeTxt.scale.x = 1.075; + timeTxt.scale.y = 1.075; + timeTxtTween = FlxTween.tween(timeTxt.scale, {x: 1, y: 1}, 0.2, { + onComplete: function(twn:FlxTween) { + timeTxtTween = null; + } + }); + } + + if (curBeat % 32 == 0 && randomSpeedThing) + { + var randomShit = FlxMath.roundDecimal(FlxG.random.float(0.4, 3), 2); + lerpSongSpeed(randomShit, 1); + } + if (camZooming && !endingSong && !startingSong && FlxG.camera.zoom < 1.35 && ClientPrefs.camZooms && curBeat % camBopInterval == 0 && !softlocked) + { + FlxG.camera.zoom += 0.015 * camBopIntensity; + camHUD.zoom += 0.03 * camBopIntensity; + } /// WOOO YOU CAN NOW MAKE IT AWESOME + + if (generatedMusic) + { + if (ClientPrefs.showNotes) notes.sort(FlxSort.byY, ClientPrefs.downScroll ? FlxSort.ASCENDING : FlxSort.DESCENDING); + } + + if (ClientPrefs.iconBounceType == 'Dave and Bambi') { + var funny:Float = Math.max(Math.min(healthBar.value,(maxHealth/0.95)),0.1); + + //health icon bounce but epic + if (!opponentChart) + { + iconP1.setGraphicSize(Std.int(iconP1.width + (50 * (funny + 0.1))),Std.int(iconP1.height - (25 * funny))); + iconP2.setGraphicSize(Std.int(iconP2.width + (50 * ((2 - funny) + 0.1))),Std.int(iconP2.height - (25 * ((2 - funny) + 0.1)))); + } else { + iconP2.setGraphicSize(Std.int(iconP2.width + (50 * funny)),Std.int(iconP2.height - (25 * funny))); + iconP1.setGraphicSize(Std.int(iconP1.width + (50 * ((2 - funny) + 0.1))),Std.int(iconP1.height - (25 * ((2 - funny) + 0.1)))); + } + } + if (ClientPrefs.iconBounceType == 'Old Psych') { + iconP1.setGraphicSize(Std.int(iconP1.width + 30)); + iconP2.setGraphicSize(Std.int(iconP2.width + 30)); + } + if (ClientPrefs.iconBounceType == 'Strident Crisis') { + var funny:Float = (healthBar.percent * 0.01) + 0.01; + + //health icon bounce but epic + iconP1.setGraphicSize(Std.int(iconP1.width + (50 * (2 + funny))),Std.int(iconP2.height - (25 * (2 + funny)))); + iconP2.setGraphicSize(Std.int(iconP2.width + (50 * (2 - funny))),Std.int(iconP2.height - (25 * (2 - funny)))); + + iconP1.scale.set(1.1, 0.8); + iconP2.scale.set(1.1, 0.8); + + FlxTween.angle(iconP1, -15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); + FlxTween.angle(iconP2, 15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); + + FlxTween.tween(iconP1, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 * gfSpeed, {ease: FlxEase.quadOut}); + FlxTween.tween(iconP2, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 * gfSpeed, {ease: FlxEase.quadOut}); + + iconP1.updateHitbox(); + iconP2.updateHitbox(); + } + if (ClientPrefs.iconBounceType == 'Plank Engine') { + iconP1.scale.x = 1.3; + iconP1.scale.y = 0.75; + iconP2.scale.x = 1.3; + iconP2.scale.y = 0.75; + FlxTween.cancelTweensOf(iconP1); + FlxTween.cancelTweensOf(iconP2); + FlxTween.tween(iconP1, {"scale.x": 1, "scale.y": 1}, Conductor.crochet / 1000, {ease: FlxEase.backOut}); + FlxTween.tween(iconP2, {"scale.x": 1, "scale.y": 1}, Conductor.crochet / 1000, {ease: FlxEase.backOut}); + if (curBeat % 4 == 0) { + iconP1.offset.x = 10; + iconP2.offset.x = -10; + iconP1.angle = -15; + iconP2.angle = 15; + FlxTween.tween(iconP1, {"offset.x": 0, angle: 0}, Conductor.crochet / 1000, {ease: FlxEase.expoOut}); + FlxTween.tween(iconP2, {"offset.x": 0, angle: 0}, Conductor.crochet / 1000, {ease: FlxEase.expoOut}); + } + } + if (ClientPrefs.iconBounceType == 'New Psych') { + iconP1.scale.set(1.2, 1.2); + iconP2.scale.set(1.2, 1.2); + } + + iconP1.updateHitbox(); + iconP2.updateHitbox(); + + if (gf != null && curBeat % Math.round(gfSpeed * gf.danceEveryNumBeats) == 0 && gf.animation.curAnim != null && !gf.animation.curAnim.name.startsWith("sing") && !gf.stunned) + { + gf.dance(); + } + if (curBeat % gfSpeed == 0 && ClientPrefs.iconBounceType == 'Golden Apple') { + curBeat % (gfSpeed * 2) == 0 * playbackRate ? { + iconP1.scale.set(1.1, 0.8); + iconP2.scale.set(1.1, 1.3); + + FlxTween.angle(iconP1, -15, 0, Conductor.crochet / 1300 / playbackRate, {ease: FlxEase.quadOut}); + FlxTween.angle(iconP2, 15, 0, Conductor.crochet / 1300 / playbackRate, {ease: FlxEase.quadOut}); + } : { + iconP1.scale.set(1.1, 1.3); + iconP2.scale.set(1.1, 0.8); + + FlxTween.angle(iconP2, -15, 0, Conductor.crochet / 1300 / playbackRate, {ease: FlxEase.quadOut}); + FlxTween.angle(iconP1, 15, 0, Conductor.crochet / 1300 / playbackRate, {ease: FlxEase.quadOut}); + } + + FlxTween.tween(iconP1, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 / playbackRate * gfSpeed, {ease: FlxEase.quadOut}); + FlxTween.tween(iconP2, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 / playbackRate * gfSpeed, {ease: FlxEase.quadOut}); + + iconP1.updateHitbox(); + iconP2.updateHitbox(); + } + if (ClientPrefs.iconBounceType == 'VS Steve') { + if (curBeat % gfSpeed == 0) + { + curBeat % (gfSpeed * 2) == 0 ? + { + iconP1.scale.set(1.1, 0.8); + iconP2.scale.set(1.1, 1.3); + //FlxTween.angle(iconP2, -15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); + //FlxTween.angle(iconP1, 15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); + } + : + { + iconP1.scale.set(1.1, 1.3); + iconP2.scale.set(1.1, 0.8); + FlxTween.angle(iconP1, -15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); + FlxTween.angle(iconP2, 15, 0, Conductor.crochet / 1300 * gfSpeed, {ease: FlxEase.quadOut}); + + } + + FlxTween.tween(iconP1, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 * gfSpeed, {ease: FlxEase.quadOut}); + FlxTween.tween(iconP2, {'scale.x': 1, 'scale.y': 1}, Conductor.crochet / 1250 * gfSpeed, {ease: FlxEase.quadOut}); + + iconP1.updateHitbox(); + iconP2.updateHitbox(); + } + } + + if (ClientPrefs.charsAndBG) { + if (curBeat % boyfriend.danceEveryNumBeats == 0 && boyfriend.animation.curAnim != null && !boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.stunned) + { + boyfriend.dance(); + } + if (curBeat % dad.danceEveryNumBeats == 0 && dad.animation.curAnim != null && !dad.animation.curAnim.name.startsWith('sing') && !dad.stunned) + { + dad.dance(); + } + + switch (curStage) + { + case 'tank': + if(!ClientPrefs.lowQuality) tankWatchtower.dance(); + foregroundSprites.forEach(function(spr:BGSprite) + { + spr.dance(); + }); + + case 'school': + if(!ClientPrefs.lowQuality) { + bgGirls.dance(); + } + + case 'mall': + if(!ClientPrefs.lowQuality) { + upperBoppers.dance(true); + } + + if(heyTimer <= 0) bottomBoppers.dance(true); + santa.dance(true); + + case 'limo': + if(!ClientPrefs.lowQuality) { + grpLimoDancers.forEach(function(dancer:BackgroundDancer) + { + dancer.dance(); + }); + } + + if (FlxG.random.bool(10) && fastCarCanDrive) + fastCarDrive(); + case "philly": + if (!trainMoving) + trainCooldown += 1; + + if (curBeat % 4 == 0) + { + curLight = FlxG.random.int(0, phillyLightsColors.length - 1, [curLight]); + phillyWindow.color = phillyLightsColors[curLight]; + phillyWindow.alpha = 1; + } + + if (curBeat % 8 == 4 && FlxG.random.bool(30) && !trainMoving && trainCooldown > 8) + { + trainCooldown = FlxG.random.int(-4, 0); + trainStart(); + } + } + + if (curStage == 'spooky' && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset) + { + lightningStrikeShit(); + } + } + lastBeatHit = curBeat; + + setOnLuas('curBeat', curBeat); //DAWGG????? + callOnLuas('onBeatHit', []); + } + + override function sectionHit() + { + super.sectionHit(); + + if (SONG.notes[curSection] != null) + { + if (generatedMusic && !endingSong && !isCameraOnForcedPos) + { + moveCameraSection(); + } + + /*if (camZooming && FlxG.camera.zoom < 1.35 && ClientPrefs.camZooms && camBopInterval == 0 && camBopIntensity == 0) + { + FlxG.camera.zoom += 0.015 * camZoomingMult; + camHUD.zoom += 0.03 * camZoomingMult; + }*/ + + if (SONG.notes[curSection].changeBPM) + { + Conductor.changeBPM(SONG.notes[curSection].bpm); + setOnLuas('curBpm', Conductor.bpm); + setOnLuas('crochet', Conductor.crochet); + setOnLuas('stepCrochet', Conductor.stepCrochet); + } + setOnLuas('mustHitSection', SONG.notes[curSection].mustHitSection); + setOnLuas('altAnim', SONG.notes[curSection].altAnim); + setOnLuas('gfSection', SONG.notes[curSection].gfSection); + } + + setOnLuas('curSection', curSection); + callOnLuas('onSectionHit', []); + } + + #if LUA_ALLOWED + public function startLuasOnFolder(luaFile:String) + { + for (script in luaArray) + { + if(script.scriptName == luaFile) return false; + } + + #if MODS_ALLOWED + var luaToLoad:String = Paths.modFolders(luaFile); + if(FileSystem.exists(luaToLoad)) + { + luaArray.push(new FunkinLua(luaToLoad)); + return true; + } + else + { + luaToLoad = Paths.getPreloadPath(luaFile); + if(FileSystem.exists(luaToLoad)) + { + luaArray.push(new FunkinLua(luaToLoad)); + return true; + } + } + #elseif sys + var luaToLoad:String = Paths.getPreloadPath(luaFile); + if(OpenFlAssets.exists(luaToLoad)) + { + luaArray.push(new FunkinLua(luaToLoad)); + return true; + } + #end + return false; + } + #end + + public function callOnLuas(event:String, args:Array, ignoreStops = true, exclusions:Array = null, excludeValues:Array = null):Dynamic { + var returnVal = FunkinLua.Function_Continue; + #if LUA_ALLOWED + if(exclusions == null) exclusions = []; + if(excludeValues == null) excludeValues = []; + + for (script in luaArray) { + if(exclusions.contains(script.scriptName)) + continue; + + var myValue = script.call(event, args); + if(myValue == FunkinLua.Function_StopLua && !ignoreStops) + break; + + if(myValue != null && myValue != FunkinLua.Function_Continue) { + returnVal = myValue; + } + } + #end + return returnVal; + } + + public function setOnLuas(variable:String, arg:Dynamic) { + #if LUA_ALLOWED + for (i in 0...luaArray.length) { + luaArray[i].set(variable, arg); + } + #end + } + + function StrumPlayAnim(isDad:Bool, id:Int, time:Float) { + var spr:StrumNote = isDad ? opponentStrums.members[id] : playerStrums.members[id]; + + if(spr != null) { + spr.playAnim('confirm', true); + spr.resetAnim = time; + } + } + + public function updateRatingCounter() { + judgeCountUpdateFrame++; + if (!ClientPrefs.noMarvJudge) + { + judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nMarvelous!!!: ' + marvs + '\nSicks!!: ' + sicks + '\nGoods!: ' + goods + '\nBads: ' + bads + '\nShits: ' + shits + '\nMisses: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + + if (ClientPrefs.hudType == 'Doki Doki+') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nVery Doki: ' + marvs + '\nDoki: ' + sicks + '\nGood: ' + goods + '\nOK: ' + bads + '\nNO: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + + if (ClientPrefs.hudType == 'VS Impostor') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSO SUSSY: ' + marvs + '\nSussy: ' + sicks + '\nSus: ' + goods + '\nSad: ' + bads + '\nAss: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + } + if (ClientPrefs.noMarvJudge) + { + judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSicks!!: ' + sicks + '\nGoods!: ' + goods + '\nBads: ' + bads + '\nShits: ' + shits + '\nMisses: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + + if (ClientPrefs.hudType == 'Doki Doki+') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nDoki: ' + sicks + '\nGood: ' + goods + '\nOK: ' + bads + '\nNO: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + + if (ClientPrefs.hudType == 'VS Impostor') judgementCounter.text = 'Combo (Max): ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(combo, false) : compactCombo) + ' (' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(maxCombo, false) : compactMaxCombo) + ')\nHits: ' + (!ClientPrefs.compactNumbers ? FlxStringUtil.formatMoney(totalNotesPlayed, false) : compactTotalPlays) + ' / ' + FlxStringUtil.formatMoney(totalNotes, false) + ' (' + FlxMath.roundDecimal((totalNotesPlayed/totalNotes) * 100, 2) + '%)\nSussy: ' + sicks + '\nSus: ' + goods + '\nSad: ' + bads + '\nAss: ' + shits + '\nMiss: ' + songMisses + (ClientPrefs.comboScoreEffect ? '\nScore Multiplier: ' + comboMultiplier + 'x' : ''); + } + judgementCounter.text += (ClientPrefs.showNPS ? '\nNPS (Max): ' + FlxStringUtil.formatMoney(nps, false) + ' (' + FlxStringUtil.formatMoney(maxNPS, false) + ')' : ''); + if (ClientPrefs.opponentRateCount) judgementCounter.text += '\n\nOpponent Hits: ' + FlxStringUtil.formatMoney(enemyHits, false) + ' / ' + FlxStringUtil.formatMoney(opponentNoteTotal, false) + ' (' + FlxMath.roundDecimal((enemyHits / opponentNoteTotal) * 100, 2) + '%)' + (ClientPrefs.showNPS ? '\nOpponent NPS (Max): ' + FlxStringUtil.formatMoney(oppNPS, false) + ' (' + FlxStringUtil.formatMoney(maxOppNPS, false) + ')' : ''); + } + + public var ratingName:String = '?'; + public var ratingString:String; + public var ratingPercent:Float; + public var ratingFC:String; + public var ratingCool:String; + public function RecalculateRating(badHit:Bool = false) { + setOnLuas('score', songScore); + setOnLuas('misses', songMisses); + setOnLuas('hits', songHits); + + var ret:Dynamic = callOnLuas('onRecalculateRating', [], false); + if(ret != FunkinLua.Function_Stop) + { + if(totalPlayed < 1) //Prevent divide by 0 + ratingName = '?'; + else + { + // Rating Percent + ratingPercent = Math.min(1, Math.max(0, totalNotesHit / totalPlayed)); + //trace((totalNotesHit / totalPlayed) + ', Total: ' + totalPlayed + ', notes hit: ' + totalNotesHit); + + if (Math.isNaN(ratingPercent)) + ratingString = '?'; + + // Rating Name + if(ratingPercent >= 1) + { + ratingName = ratingStuff[ratingStuff.length-1][0]; //Uses last string + } + else + { + for (i in 0...ratingStuff.length-1) + { + if(ratingPercent < ratingStuff[i][1]) + { + ratingName = ratingStuff[i][0]; + break; + } + } + } + } + + // Rating FC + ratingFC = ""; + if (totalPlayed == 0) ratingFC = "No Play"; + if (marvs > 0) ratingFC = "MFC"; + if (sicks > 0) ratingFC = "SFC"; + if (goods > 0) ratingFC = "GFC"; + if (bads > 0) ratingFC = "BFC"; + if (shits > 0) ratingFC = "FC"; + if (songMisses > 0 && songMisses < 10) ratingFC = "SDCB"; + if (songMisses >= 10) ratingFC = "Clear"; + if (songMisses >= 100) ratingFC = "TDSB"; + if (songMisses >= 1000) ratingFC = "QDSB"; + if (songMisses >= 100000) ratingFC = "STDCB"; + else if (songMisses >= 10000000) ratingFC = "SPDCB"; //i have no idea how you'd get a million misses but oh well + + + if (!ClientPrefs.longFCName) + { + if (ClientPrefs.hudType == "VS Impostor") + { + if (totalPlayed == 0) ratingFC = " [No Play]"; + if (marvs > 0) ratingFC = " [MFC]"; + if (sicks > 0) ratingFC = " [SFC]"; + if (goods > 0) ratingFC = " [GFC]"; + if (bads > 0) ratingFC = " [BFC]"; + if (shits > 0) ratingFC = " [FC]"; + if (songMisses > 0 && songMisses < 10) ratingFC = " [SDCB]"; + if (songMisses >= 10) ratingFC = " [Clear]"; + if (songMisses >= 100) ratingFC = " [TDSB]"; + if (songMisses >= 1000) ratingFC = " [QDSB]"; + if (songMisses >= 100000) ratingFC = " [STDCB]"; + else if (songMisses >= 10000000) ratingFC = " [SPDCB]"; //i have no idea how you'd get a million misses but oh well + } + + if (ClientPrefs.hudType == "Tails Gets Trolled V4") + { + if (totalPlayed == 0) ratingFC = "No Play"; + if (marvs > 0) ratingFC = "KFC"; + if (sicks > 0) ratingFC = "AFC"; + if (goods > 0) ratingFC = "CFC"; + if (bads > 0) ratingFC = "SDC"; + if (shits > 0) ratingFC = "FC"; + if (songMisses > 0 && songMisses < 10) ratingFC = "SDCB"; + if (songMisses >= 10) ratingFC = "Clear"; + if (songMisses >= 100) ratingFC = "TDSB"; + if (songMisses >= 1000) ratingFC = "QDSB"; + if (songMisses >= 100000) ratingFC = "STDCB"; + else if (songMisses >= 10000000) ratingFC = "SPDCB"; //i have no idea how you'd get a million misses but oh well + } + + // Rating FC + if (ClientPrefs.hudType == 'Kade Engine' || ClientPrefs.hudType == 'Doki Doki+') { + ratingFC = "?"; + if (totalPlayed == 0) ratingFC = "No Play"; + if (marvs > 0) ratingFC = "(MFC)"; + if (sicks > 0) ratingFC = "(SFC)"; + if (goods > 0) ratingFC = "(GFC)"; + if (bads > 0) ratingFC = "(BFC)"; + if (shits > 0) ratingFC = "(FC)"; + if (songMisses > 0 && songMisses < 10) ratingFC = "(SDCB)"; + if (songMisses >= 10) ratingFC = "(Clear)"; + if (songMisses >= 100) ratingFC = "(TDSB)"; + if (songMisses >= 1000) ratingFC = "(QDSB)"; + if (songMisses >= 100000) ratingFC = "(STDCB)"; + else if (songMisses >= 10000000) ratingFC = "(SPDCB)"; //i have no idea how you'd get a million misses but oh well + } + } + if (ClientPrefs.longFCName) + { + if (totalPlayed == 0) ratingFC = "No Play"; + if (marvs > 0) ratingFC = "Marvelous Full Combo"; + if (sicks > 0) ratingFC = "Sick Full Combo"; + if (goods > 0) ratingFC = "Great Full Combo"; + if (bads > 0) ratingFC = "Bad Full Combo"; + if (shits > 0) ratingFC = "Shit Full Combo"; + if (songMisses > 0 && songMisses < 10) ratingFC = "Single Digit Combo Breaks"; + if (songMisses >= 10) ratingFC = "Double Digit Combo Breaks"; + if (songMisses >= 100) ratingFC = "Triple Digit Combo Breaks"; + if (songMisses >= 1000) ratingFC = "Quadruple Digit Combo Breaks"; + if (songMisses >= 10000) ratingFC = "Quintuple Digit Combo Breaks"; + if (songMisses >= 100000) ratingFC = "Sixtuple Digit Combo Breaks"; + else if (songMisses >= 10000000) ratingFC = "Septuple Digit Combo Breaks"; //i have no idea how you'd get a million misses but oh well + if (ClientPrefs.hudType == "VS Impostor") + { + if (totalPlayed == 0) ratingFC = " [No Play]"; + if (marvs > 0) ratingFC = " [Marvelous Full Combo]"; + if (sicks > 0) ratingFC = " [Sick Full Combo]"; + if (goods > 0) ratingFC = " [Great Full Combo]"; + if (bads > 0) ratingFC = " [Bad Full Combo]"; + if (shits > 0) ratingFC = " [Shit Full Combo]"; + if (songMisses > 0 && songMisses < 10) ratingFC = " [Single Digit Combo Breaks]"; + if (songMisses >= 10) ratingFC = " [Double Digit Combo Breaks]"; + if (songMisses >= 100) ratingFC = " [Triple Digit Combo Breaks]"; + if (songMisses >= 1000) ratingFC = " [Quadruple Digit Combo Breaks]"; + if (songMisses >= 10000) ratingFC = " [Quintuple Digit Combo Breaks]"; + if (songMisses >= 100000) ratingFC = " [Sixtuple Digit Combo Breaks]"; + else if (songMisses >= 10000000) ratingFC = " [Septuple Digit Combo Breaks]"; //i have no idea how you'd get a million misses but oh well + } + + if (ClientPrefs.hudType == "Tails Gets Trolled V4") + { + if (totalPlayed == 0) ratingFC = "No Play"; + if (marvs > 0) ratingFC = "Killer Full Combo"; + if (sicks > 0) ratingFC = "Awesome Full Combo"; + if (goods > 0) ratingFC = "Cool Full Combo"; + if (bads > 0) ratingFC = "Gay Full Combo"; + if (shits > 0) ratingFC = "Retarded Full Combo"; + if (songMisses > 0 && songMisses < 10) ratingFC = "Single Digit Combo Breaks"; + if (songMisses >= 10) ratingFC = "Double Digit Combo Breaks"; + if (songMisses >= 100) ratingFC = "Triple Digit Combo Breaks"; + if (songMisses >= 1000) ratingFC = "Quadruple Digit Combo Breaks"; + if (songMisses >= 10000) ratingFC = "Quintuple Digit Combo Breaks"; + if (songMisses >= 100000) ratingFC = "Sixtuple Digit Combo Breaks"; + else if (songMisses >= 10000000) ratingFC = "Septuple Digit Combo Breaks"; //i have no idea how you'd get a million misses but oh well + } + + // Rating FC + if (ClientPrefs.hudType == 'Kade Engine' || ClientPrefs.hudType == 'Doki Doki+') { + ratingFC = "?"; + if (totalPlayed == 0) ratingFC = "(No Play)"; + if (marvs > 0) ratingFC = "(Marvelous Full Combo)"; + if (sicks > 0) ratingFC = "(Sick Full Combo)"; + if (goods > 0) ratingFC = "(Great Full Combo)"; + if (bads > 0) ratingFC = "(Bad Full Combo)"; + if (shits > 0) ratingFC = "(Shit Full Combo)"; + if (songMisses > 0 && songMisses < 10) ratingFC = "(Single Digit Combo Breaks)"; + if (songMisses >= 10) ratingFC = "(Double Digit Combo Breaks)"; + if (songMisses >= 100) ratingFC = "(Triple Digit Combo Breaks)"; + if (songMisses >= 1000) ratingFC = "(Quadruple Digit Combo Breaks)"; + if (songMisses >= 10000) ratingFC = "(Quintuple Digit Combo Breaks)"; + if (songMisses >= 100000) ratingFC = "(Sixtuple Digit Combo Breaks)"; + else if (songMisses >= 10000000) ratingFC = "(Septuple Digit Combo Breaks)"; //i have no idea how you'd get a million misses but oh well + } + } + + ratingCool = ""; + if (ratingPercent*100 <= 60) ratingCool = " F"; + if (ratingPercent*100 >= 60) ratingCool = " D"; + if (ratingPercent*100 >= 60) ratingCool = " C"; + if (ratingPercent*100 >= 70) ratingCool = " B"; + if (ratingPercent*100 >= 80) ratingCool = " A"; + if (ratingPercent*100 >= 85) ratingCool = " A."; + if (ratingPercent*100 >= 90) ratingCool = " A:"; + if (ratingPercent*100 >= 93) ratingCool = " AA"; + if (ratingPercent*100 >= 96.50) ratingCool = " AA."; + if (ratingPercent*100 >= 99) ratingCool = " AA:"; + if (ratingPercent*100 >= 99.70) ratingCool = " AAA"; + if (ratingPercent*100 >= 99.80) ratingCool = " AAA."; + if (ratingPercent*100 >= 99.90) ratingCool = " AAA:"; + if (ratingPercent*100 >= 99.955) ratingCool = " AAAA"; + if (ratingPercent*100 >= 99.970) ratingCool = " AAAA."; + if (ratingPercent*100 >= 99.980) ratingCool = " AAAA:"; + if (ratingPercent*100 >= 99.9935) ratingCool = " AAAAA"; + } + + setOnLuas('rating', ratingPercent); + setOnLuas('ratingName', ratingName); + setOnLuas('ratingFC', ratingFC); + setOnLuas('ratingCool', ratingCool); + } + + #if ACHIEVEMENTS_ALLOWED + private function checkForAchievement(achievesToCheck:Array = null):String + { + if(chartingMode) return null; + + var usedPractice:Bool = (ClientPrefs.getGameplaySetting('practice', false) || ClientPrefs.getGameplaySetting('botplay', false)); + for (i in 0...achievesToCheck.length) { + var achievementName:String = achievesToCheck[i]; + if(!Achievements.isAchievementUnlocked(achievementName) && !cpuControlled && Achievements.exists(achievementName)) { + var unlock:Bool = false; + + if (achievementName.contains(WeekData.getWeekFileName()) && achievementName.endsWith('nomiss')) // any FC achievements, name should be "weekFileName_nomiss", e.g: "weekd_nomiss"; + { + if(isStoryMode && campaignMisses + songMisses < 1 && CoolUtil.difficultyString() == 'HARD' + && storyPlaylist.length <= 1 && !changedDifficulty && !usedPractice) + unlock = true; + } + switch(achievementName) + { + case 'ur_bad': + if(ratingPercent < 0.2 && !practiceMode) { + unlock = true; + } + case 'ur_good': + if(ratingPercent >= 1 && !usedPractice) { + unlock = true; + } + case 'roadkill_enthusiast': + if(Achievements.henchmenDeath >= 100) { + unlock = true; + } + case 'oversinging': + if(boyfriend.holdTimer >= 10 && !usedPractice) { + unlock = true; + } + case 'hype': + if(!boyfriendIdled && !usedPractice) { + unlock = true; + } + case 'two_keys': + if(!usedPractice) { + var howManyPresses:Int = 0; + for (j in 0...keysPressed.length) { + if(keysPressed[j]) howManyPresses++; + } + + if(howManyPresses <= 2) { + unlock = true; + } + } + case 'toastie': + if(/*ClientPrefs.framerate <= 60 &&*/ !ClientPrefs.shaders && ClientPrefs.lowQuality && !ClientPrefs.globalAntialiasing) { + unlock = true; + } + case 'debugger': + if(Paths.formatToSongPath(SONG.song) == 'test' && !usedPractice) { + unlock = true; + } + } + + if(unlock) { + Achievements.unlockAchievement(achievementName); + return achievementName; + } + } + } + return null; + } + #end + + var curLight:Int = -1; + var curLightEvent:Int = -1; +} +//WEVE DONE IT, WE'VE HIT 10,000 LINES //10-24-2023: nvm were back down to 9800 lines \ No newline at end of file diff --git a/source/Song.hx b/source/Song.hx index 9e02ad8aaaa..26c4c175870 100644 --- a/source/Song.hx +++ b/source/Song.hx @@ -1,148 +1,148 @@ -package; - -import Section.SwagSection; -import haxe.Json; -import haxe.format.JsonParser; -import lime.utils.Assets; - -#if sys -import sys.io.File; -import sys.FileSystem; -#end - -using StringTools; - -typedef SwagSong = -{ - var song:String; - var notes:Array; - var events:Array; - var bpm:Float; - var needsVoices:Bool; - var speed:Float; - - var player1:String; - var player2:String; - var gfVersion:String; - var stage:String; - - var songCredit:String; - - var arrowSkin:String; - var splashSkin:String; - var validScore:Bool; -} - -class Song -{ - public var song:String; - public var notes:Array; - public var events:Array; - public var bpm:Float; - public var needsVoices:Bool = true; - public var arrowSkin:String; - public var splashSkin:String; - public var speed:Float = 1; - public var stage:String; - public var songCredit:String; - public var player1:String = 'bf'; - public var player2:String = 'dad'; - public var gfVersion:String = 'gf'; - public var gfVersion2:String = 'gf-bent'; - - private static function onLoadJson(songJson:Dynamic) // Convert old charts to newest format - { - if(songJson.gfVersion == null) - { - songJson.gfVersion = songJson.player3; - songJson.player3 = null; - } - - if(songJson.events == null) - { - songJson.events = []; - for (secNum in 0...songJson.notes.length) - { - var sec:SwagSection = songJson.notes[secNum]; - - var i:Int = 0; - var notes:Array = sec.sectionNotes; - var len:Int = notes.length; - while(i < len) - { - var note:Array = notes[i]; - if(note[1] < 0) - { - songJson.events.push([note[0], [[note[2], note[3], note[4]]]]); - notes.remove(note); - len = notes.length; - } - else i++; - } - } - } - } - - public function new(song, notes, bpm) - { - this.song = song; - this.notes = notes; - this.bpm = bpm; - } - - public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong - { - var rawJson = null; - - var formattedFolder:String = Paths.formatToSongPath(folder); - var formattedSong:String = Paths.formatToSongPath(jsonInput); - #if MODS_ALLOWED - var moddyFile:String = Paths.modsJson(formattedFolder + '/' + formattedSong); - if(FileSystem.exists(moddyFile)) { - rawJson = File.getContent(moddyFile).trim(); - } - #end - - if(rawJson == null) { - #if sys - rawJson = File.getContent(SUtil.getPath() + Paths.json(formattedFolder + '/' + formattedSong)).trim(); - #else - rawJson = Assets.getText(Paths.json(formattedFolder + '/' + formattedSong)).trim(); - #end - } - - while (!rawJson.endsWith("}")) - { - rawJson = rawJson.substr(0, rawJson.length - 1); - // LOL GOING THROUGH THE BULLSHIT TO CLEAN IDK WHATS STRANGE - } - - // FIX THE CASTING ON WINDOWS/NATIVE - // Windows??? - // trace(songData); - - // trace('LOADED FROM JSON: ' + songData.notes); - /* - for (i in 0...songData.notes.length) - { - trace('LOADED FROM JSON: ' + songData.notes[i].sectionNotes); - // songData.notes[i].sectionNotes = songData.notes[i].sectionNotes - } - - daNotes = songData.notes; - daSong = songData.song; - daBpm = songData.bpm; */ - - var songJson:Dynamic = parseJSONshit(rawJson); - if(jsonInput != 'events') StageData.loadDirectory(songJson); - onLoadJson(songJson); - return songJson; - } - - public static function parseJSONshit(rawJson:String):SwagSong - { - var swagShit:SwagSong = cast Json.parse(rawJson).song; - swagShit.validScore = true; - return swagShit; - } -} +package; + +import Section.SwagSection; +import haxe.Json; +import haxe.format.JsonParser; +import lime.utils.Assets; + +#if sys +import sys.io.File; +import sys.FileSystem; +#end + +using StringTools; + +typedef SwagSong = +{ + var song:String; + var notes:Array; + var events:Array; + var bpm:Float; + var needsVoices:Bool; + var speed:Float; + + var player1:String; + var player2:String; + var gfVersion:String; + var stage:String; + + var songCredit:String; + + var arrowSkin:String; + var splashSkin:String; + var validScore:Bool; +} + +class Song +{ + public var song:String; + public var notes:Array; + public var events:Array; + public var bpm:Float; + public var needsVoices:Bool = true; + public var arrowSkin:String; + public var splashSkin:String; + public var speed:Float = 1; + public var stage:String; + public var songCredit:String; + public var player1:String = 'bf'; + public var player2:String = 'dad'; + public var gfVersion:String = 'gf'; + public var gfVersion2:String = 'gf-bent'; + + private static function onLoadJson(songJson:Dynamic) // Convert old charts to newest format + { + if(songJson.gfVersion == null) + { + songJson.gfVersion = songJson.player3; + songJson.player3 = null; + } + + if(songJson.events == null) + { + songJson.events = []; + for (secNum in 0...songJson.notes.length) + { + var sec:SwagSection = songJson.notes[secNum]; + + var i:Int = 0; + var notes:Array = sec.sectionNotes; + var len:Int = notes.length; + while(i < len) + { + var note:Array = notes[i]; + if(note[1] < 0) + { + songJson.events.push([note[0], [[note[2], note[3], note[4]]]]); + notes.remove(note); + len = notes.length; + } + else i++; + } + } + } + } + + public function new(song, notes, bpm) + { + this.song = song; + this.notes = notes; + this.bpm = bpm; + } + + public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong + { + var rawJson = null; + + var formattedFolder:String = Paths.formatToSongPath(folder); + var formattedSong:String = Paths.formatToSongPath(jsonInput); + #if MODS_ALLOWED + var moddyFile:String = Paths.modsJson(formattedFolder + '/' + formattedSong); + if(FileSystem.exists(moddyFile)) { + rawJson = File.getContent(moddyFile).trim(); + } + #end + + if(rawJson == null) { + #if sys + rawJson = File.getContent(SUtil.getPath() + Paths.json(formattedFolder + '/' + formattedSong)).trim(); + #else + rawJson = Assets.getText(Paths.json(formattedFolder + '/' + formattedSong)).trim(); + #end + } + + while (!rawJson.endsWith("}")) + { + rawJson = rawJson.substr(0, rawJson.length - 1); + // LOL GOING THROUGH THE BULLSHIT TO CLEAN IDK WHATS STRANGE + } + + // FIX THE CASTING ON WINDOWS/NATIVE + // Windows??? + // trace(songData); + + // trace('LOADED FROM JSON: ' + songData.notes); + /* + for (i in 0...songData.notes.length) + { + trace('LOADED FROM JSON: ' + songData.notes[i].sectionNotes); + // songData.notes[i].sectionNotes = songData.notes[i].sectionNotes + } + + daNotes = songData.notes; + daSong = songData.song; + daBpm = songData.bpm; */ + + var songJson:Dynamic = parseJSONshit(rawJson); + if(jsonInput != 'events') StageData.loadDirectory(songJson); + onLoadJson(songJson); + return songJson; + } + + public static function parseJSONshit(rawJson:String):SwagSong + { + var swagShit:SwagSong = cast Json.parse(rawJson).song; + swagShit.validScore = true; + return swagShit; + } +} diff --git a/source/TitleState.hx b/source/TitleState.hx index 2f668ae8fb1..4597205fcb3 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -1,811 +1,811 @@ -package; - -#if desktop -import sys.thread.Thread; -#end -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.FlxState; -import flixel.input.keyboard.FlxKey; -import flixel.addons.display.FlxGridOverlay; -import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; -import flixel.addons.transition.FlxTransitionableState; -import flixel.addons.transition.TransitionData; -import haxe.Json; -import openfl.display.Bitmap; -import openfl.display.BitmapData; -#if MODS_ALLOWED -import sys.FileSystem; -import sys.io.File; -#end -import options.GraphicsSettingsSubState; -//import flixel.graphics.FlxGraphic; -import flixel.graphics.frames.FlxAtlasFrames; -import flixel.graphics.frames.FlxFrame; -import flixel.group.FlxGroup; -import flixel.input.gamepad.FlxGamepad; -import flixel.math.FlxMath; -import flixel.math.FlxPoint; -import flixel.math.FlxRect; -import flixel.system.FlxSound; -import flixel.system.ui.FlxSoundTray; -import flixel.text.FlxText; -import flixel.tweens.FlxEase; -import flixel.tweens.FlxTween; -import flixel.util.FlxColor; -import flixel.util.FlxTimer; -import openfl.Assets; - -using StringTools; -typedef TitleData = -{ - - titlex:Float, - titley:Float, - startx:Float, - starty:Float, - gfx:Float, - gfy:Float, - backgroundSprite:String, - bpm:Int -} -class TitleState extends MusicBeatState -{ - public static var muteKeys:Array = [FlxKey.ZERO]; - public static var volumeDownKeys:Array = [FlxKey.NUMPADMINUS, FlxKey.MINUS]; - public static var volumeUpKeys:Array = [FlxKey.NUMPADPLUS, FlxKey.PLUS]; - - public static var initialized:Bool = false; - - var blackScreen:FlxSprite; - var credGroup:FlxGroup; - var credTextShit:Alphabet; - var textGroup:FlxGroup; - var ngSpr:FlxSprite; - - var titleTextColors:Array = [0xFF33FFFF, 0xFF3333CC]; - var titleTextAlphas:Array = [1, .64]; - - var curWacky:Array = []; - - var wackyImage:FlxSprite; - - #if TITLE_SCREEN_EASTER_EGG - var easterEggKeys:Array = [ - 'SHADOW', 'RIVER', 'SHUBS', 'BBPANZU' - ]; - var allowedKeys:String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - var easterEggKeysBuffer:String = ''; - #end - - var mustUpdate:Bool = false; - - public static var titleJSON:TitleData; - - public static var updateVersion:String = ''; - - override public function create():Void - { - Paths.clearStoredMemory(); - Paths.clearUnusedMemory(); - - #if android - FlxG.android.preventDefaultKeys = [BACK]; - #end - - MusicBeatState.windowNameSuffix = ""; - - #if LUA_ALLOWED - Paths.pushGlobalMods(); - #end - // Just to load a mod on start up if ya got one. For mods that change the menu music and bg - WeekData.loadTheFirstEnabledMod(); - MusicBeatState.windowNamePrefix = Assets.getText(Paths.txt("windowTitleBase", "preload")); - - //trace(path, FileSystem.exists(path)); - /*#if (polymod && !html5) - if (sys.FileSystem.exists('mods/')) { - var folders:Array = []; - for (file in sys.FileSystem.readDirectory('mods/')) { - var path = haxe.io.Path.join(['mods/', file]); - if (sys.FileSystem.isDirectory(path)) { - folders.push(file); - } - } - if(folders.length > 0) { - polymod.Polymod.init({modRoot: "mods", dirs: folders}); - } - } - #end*/ - - FlxG.game.focusLostFramerate = 60; - FlxG.sound.muteKeys = muteKeys; - FlxG.sound.volumeDownKeys = volumeDownKeys; - FlxG.sound.volumeUpKeys = volumeUpKeys; - FlxG.keys.preventDefaultKeys = [TAB]; - - PlayerSettings.init(); - - curWacky = FlxG.random.getObject(getIntroTextShit()); - - // DEBUG BULLSHIT - - swagShader = new ColorSwap(); - super.create(); - - FlxG.save.bind('funkin', CoolUtil.getSavePath()); - - ClientPrefs.loadPrefs(); - - #if (CHECK_FOR_UPDATES && !android) - if(ClientPrefs.checkForUpdates && !closedState) { - trace('checking for update'); - var http = new haxe.Http("https://raw.githubusercontent.com/JordanSantiagoYT/FNF-PsychEngine-NoBotplayLag/main/version.downloadMe"); - var returnedData:Array = []; - - http.onData = function (data:String) - { - returnedData[0] = data.substring(0, data.indexOf(';')); - returnedData[1] = data.substring(data.indexOf('-'), data.length); - updateVersion = returnedData[0]; - var curVersion:String = MainMenuState.psychEngineJSVersion.trim(); - trace('version online: ' + updateVersion + ', your version: ' + curVersion); - if(updateVersion != curVersion) { - trace('versions arent matching!'); - OutdatedState.currChanges = returnedData[1]; - mustUpdate = true; - } - if(updateVersion == curVersion) { - trace('the versions match!'); - } - } - - http.onError = function (error) { - trace('error: $error'); - } - - http.request(); - } - #end - - Highscore.load(); - - // IGNORE THIS!!! - titleJSON = Json.parse(Paths.getTextFromFile('images/gfDanceTitle.json')); - - #if TITLE_SCREEN_EASTER_EGG - if (FlxG.save.data.psychDevsEasterEgg == null) FlxG.save.data.psychDevsEasterEgg = ''; //Crash prevention - switch(FlxG.save.data.psychDevsEasterEgg.toUpperCase()) - { - case 'SHADOW': - titleJSON.gfx += 210; - titleJSON.gfy += 40; - case 'RIVER': - titleJSON.gfx += 100; - titleJSON.gfy += 20; - case 'SHUBS': - titleJSON.gfx += 160; - titleJSON.gfy -= 10; - case 'BBPANZU': - titleJSON.gfx += 45; - titleJSON.gfy += 100; - } - #end - - if(!initialized) - { - if(FlxG.save.data != null && FlxG.save.data.fullscreen) - { - FlxG.fullscreen = FlxG.save.data.fullscreen; - //trace('LOADED FULLSCREEN SETTING!!'); - } - persistentUpdate = true; - persistentDraw = true; - } - - if (FlxG.save.data.weekCompleted != null) - { - StoryMenuState.weekCompleted = FlxG.save.data.weekCompleted; - } - - FlxG.mouse.visible = false; - #if FREEPLAY - MusicBeatState.switchState(new FreeplayState()); - #elseif CHARTING - MusicBeatState.switchState(new ChartingState()); - #else - if(FlxG.save.data.flashing == null && !FlashingState.leftState) { - FlxTransitionableState.skipNextTransIn = true; - FlxTransitionableState.skipNextTransOut = true; - MusicBeatState.switchState(new FlashingState()); - } else { - if (initialized) - startIntro(); - else - { - new FlxTimer().start(1, function(tmr:FlxTimer) - { - startIntro(); - }); - } - } - #end - } - - var logoBl:FlxSprite; - var gfDance:FlxSprite; - var danceLeft:Bool = false; - var titleText:FlxSprite; - var swagShader:ColorSwap = null; - - function startIntro() - { - if (!initialized) - { - /*var diamond:FlxGraphic = FlxGraphic.fromClass(GraphicTransTileDiamond); - diamond.persist = true; - diamond.destroyOnNoUse = false; - - FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 1, new FlxPoint(0, -1), {asset: diamond, width: 32, height: 32}, - new FlxRect(-300, -300, FlxG.width * 1.8, FlxG.height * 1.8)); - FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 0.7, new FlxPoint(0, 1), - {asset: diamond, width: 32, height: 32}, new FlxRect(-300, -300, FlxG.width * 1.8, FlxG.height * 1.8)); - - transIn = FlxTransitionableState.defaultTransIn; - transOut = FlxTransitionableState.defaultTransOut;*/ - - // HAD TO MODIFY SOME BACKEND SHIT - // IF THIS PR IS HERE IF ITS ACCEPTED UR GOOD TO GO - // https://github.com/HaxeFlixel/flixel-addons/pull/348 - - // var music:FlxSound = new FlxSound(); - // music.loadStream(Paths.music('freakyMenu')); - // FlxG.sound.list.add(music); - // music.play(); - - if(FlxG.sound.music == null) { - FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic), 0); - } - } - - switch(ClientPrefs.daMenuMusic) - { - case 'Mashup' | 'VS Impostor' | 'VS Nonsense V2' | 'Base Game': - Conductor.changeBPM(titleJSON.bpm); - case 'Dave & Bambi': - Conductor.changeBPM(148); - case 'Dave & Bambi (Old)': - Conductor.changeBPM(150); - case 'DDTO+': - Conductor.changeBPM(120); - } - persistentUpdate = true; - - var bg:FlxSprite = new FlxSprite(); - - if (titleJSON.backgroundSprite != null && titleJSON.backgroundSprite.length > 0 && titleJSON.backgroundSprite != "none"){ - bg.loadGraphic(Paths.image(titleJSON.backgroundSprite)); - }else{ - bg.makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - } - - // bg.antialiasing = ClientPrefs.globalAntialiasing; - // bg.setGraphicSize(Std.int(bg.width * 0.6)); - // bg.updateHitbox(); - add(bg); - - logoBl = new FlxSprite(titleJSON.titlex, titleJSON.titley); - logoBl.frames = Paths.getSparrowAtlas('logoBumpin'); - - logoBl.antialiasing = ClientPrefs.globalAntialiasing; - logoBl.animation.addByPrefix('bump', 'logo bumpin', 24, false); - logoBl.animation.play('bump'); - logoBl.updateHitbox(); - // logoBl.screenCenter(); - // logoBl.color = FlxColor.BLACK; - - swagShader = new ColorSwap(); - gfDance = new FlxSprite(titleJSON.gfx, titleJSON.gfy); - - var easterEgg:String = FlxG.save.data.psychDevsEasterEgg; - if(easterEgg == null) easterEgg = ''; //html5 fix - - switch(easterEgg.toUpperCase()) - { - #if TITLE_SCREEN_EASTER_EGG - case 'SHADOW': - gfDance.frames = Paths.getSparrowAtlas('ShadowBump'); - gfDance.animation.addByPrefix('danceLeft', 'Shadow Title Bump', 24); - gfDance.animation.addByPrefix('danceRight', 'Shadow Title Bump', 24); - case 'RIVER': - gfDance.frames = Paths.getSparrowAtlas('RiverBump'); - gfDance.animation.addByIndices('danceLeft', 'River Title Bump', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); - gfDance.animation.addByIndices('danceRight', 'River Title Bump', [29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); - case 'SHUBS': - gfDance.frames = Paths.getSparrowAtlas('ShubBump'); - gfDance.animation.addByPrefix('danceLeft', 'Shub Title Bump', 24, false); - gfDance.animation.addByPrefix('danceRight', 'Shub Title Bump', 24, false); - case 'BBPANZU': - gfDance.frames = Paths.getSparrowAtlas('BBBump'); - gfDance.animation.addByIndices('danceLeft', 'BB Title Bump', [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27], "", 24, false); - gfDance.animation.addByIndices('danceRight', 'BB Title Bump', [27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], "", 24, false); - #end - - default: - //EDIT THIS ONE IF YOU'RE MAKING A SOURCE CODE MOD!!!! - //EDIT THIS ONE IF YOU'RE MAKING A SOURCE CODE MOD!!!! - //EDIT THIS ONE IF YOU'RE MAKING A SOURCE CODE MOD!!!! - gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle'); - gfDance.animation.addByIndices('danceLeft', 'gfDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); - gfDance.animation.addByIndices('danceRight', 'gfDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); - } - gfDance.antialiasing = ClientPrefs.globalAntialiasing; - - add(gfDance); - gfDance.shader = swagShader.shader; - add(logoBl); - logoBl.shader = swagShader.shader; - - titleText = new FlxSprite(titleJSON.startx, titleJSON.starty); - #if (desktop || android && MODS_ALLOWED) - var path = SUtil.getPath() + "mods/" + Paths.currentModDirectory + "/images/titleEnter.png"; - //trace(path, FileSystem.exists(path)); - if (!FileSystem.exists(path)){ - path = SUtil.getPath() + "mods/images/titleEnter.png"; - } - //trace(path, FileSystem.exists(path)); - if (!FileSystem.exists(path)){ - path = SUtil.getPath() + "assets/images/titleEnter.png"; - } - //trace(path, FileSystem.exists(path)); - titleText.frames = FlxAtlasFrames.fromSparrow(BitmapData.fromFile(path),File.getContent(StringTools.replace(path,".png",".xml"))); - #else - - titleText.frames = Paths.getSparrowAtlas('titleEnter'); - #end - var animFrames:Array = []; - @:privateAccess { - titleText.animation.findByPrefix(animFrames, "ENTER IDLE"); - titleText.animation.findByPrefix(animFrames, "ENTER FREEZE"); - } - - if (animFrames.length > 0) { - newTitle = true; - - titleText.animation.addByPrefix('idle', "ENTER IDLE", 24); - titleText.animation.addByPrefix('press', ClientPrefs.flashing ? "ENTER PRESSED" : "ENTER FREEZE", 24); - } - else { - newTitle = false; - - titleText.animation.addByPrefix('idle', "Press Enter to Begin", 24); - titleText.animation.addByPrefix('press', "ENTER PRESSED", 24); - } - - titleText.antialiasing = ClientPrefs.globalAntialiasing; - titleText.animation.play('idle'); - titleText.updateHitbox(); - // titleText.screenCenter(X); - add(titleText); - - var logo:FlxSprite = new FlxSprite().loadGraphic(Paths.image('logo')); - logo.screenCenter(); - logo.antialiasing = ClientPrefs.globalAntialiasing; - // add(logo); - - // FlxTween.tween(logoBl, {y: logoBl.y + 50}, 0.6, {ease: FlxEase.quadInOut, type: PINGPONG}); - // FlxTween.tween(logo, {y: logoBl.y + 50}, 0.6, {ease: FlxEase.quadInOut, type: PINGPONG, startDelay: 0.1}); - - credGroup = new FlxGroup(); - add(credGroup); - textGroup = new FlxGroup(); - - blackScreen = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - credGroup.add(blackScreen); - - credTextShit = new Alphabet(0, 0, "", true); - credTextShit.screenCenter(); - - // credTextShit.alignment = CENTER; - - credTextShit.visible = false; - - ngSpr = new FlxSprite(0, FlxG.height * 0.52).loadGraphic(Paths.image('newgrounds_logo')); - add(ngSpr); - ngSpr.visible = false; - ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.8)); - ngSpr.updateHitbox(); - ngSpr.screenCenter(X); - ngSpr.antialiasing = ClientPrefs.globalAntialiasing; - - FlxTween.tween(credTextShit, {y: credTextShit.y + 20}, 2.9, {ease: FlxEase.quadInOut, type: PINGPONG}); - - if (initialized) - skipIntro(); - else - initialized = true; - - // credGroup.add(credTextShit); - } - - function getIntroTextShit():Array> - { - var fullText:String = Assets.getText(Paths.txt('introText')); - - var firstArray:Array = fullText.split('\n'); - var swagGoodArray:Array> = []; - - for (i in firstArray) - { - swagGoodArray.push(i.split('--')); - } - - return swagGoodArray; - } - - var transitioning:Bool = false; - private static var playJingle:Bool = false; - - var newTitle:Bool = false; - var titleTimer:Float = 0; - - override function update(elapsed:Float) - { - if (FlxG.sound.music != null) - Conductor.songPosition = FlxG.sound.music.time; - // FlxG.watch.addQuick('amp', FlxG.sound.music.amplitude); - - var pressedEnter:Bool = FlxG.keys.justPressed.ENTER || controls.ACCEPT; - - #if android - for (touch in FlxG.touches.list) { - if (touch.justPressed) { - pressedEnter = true; - } - } - #end - - var gamepad:FlxGamepad = FlxG.gamepads.lastActive; - - if (gamepad != null) - { - if (gamepad.justPressed.START) - pressedEnter = true; - - #if switch - if (gamepad.justPressed.B) - pressedEnter = true; - #end - } - - if (newTitle) { - titleTimer += CoolUtil.boundTo(elapsed, 0, 1); - if (titleTimer > 2) titleTimer -= 2; - } - - // EASTER EGG - - if (initialized && !transitioning && skippedIntro) - { - if (newTitle && !pressedEnter) - { - var timer:Float = titleTimer; - if (timer >= 1) - timer = (-timer) + 2; - - timer = FlxEase.quadInOut(timer); - - titleText.color = FlxColor.interpolate(titleTextColors[0], titleTextColors[1], timer); - titleText.alpha = FlxMath.lerp(titleTextAlphas[0], titleTextAlphas[1], timer); - } - - if(pressedEnter) - { - titleText.color = FlxColor.WHITE; - titleText.alpha = 1; - - if(titleText != null) titleText.animation.play('press'); - - FlxG.camera.flash(ClientPrefs.flashing ? FlxColor.WHITE : 0x4CFFFFFF, 1); - FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); - - transitioning = true; - // FlxG.sound.music.stop(); - - new FlxTimer().start(1, function(tmr:FlxTimer) - { - if (mustUpdate) { - MusicBeatState.switchState(new OutdatedState()); - } else { - MusicBeatState.switchState(new MainMenuState()); - } - closedState = true; - }); - // FlxG.sound.play(Paths.music('titleShoot'), 0.7); - } - #if TITLE_SCREEN_EASTER_EGG - else if (FlxG.keys.firstJustPressed() != FlxKey.NONE) - { - var keyPressed:FlxKey = FlxG.keys.firstJustPressed(); - var keyName:String = Std.string(keyPressed); - if(allowedKeys.contains(keyName)) { - easterEggKeysBuffer += keyName; - if(easterEggKeysBuffer.length >= 32) easterEggKeysBuffer = easterEggKeysBuffer.substring(1); - //trace('Test! Allowed Key pressed!!! Buffer: ' + easterEggKeysBuffer); - - for (wordRaw in easterEggKeys) - { - var word:String = wordRaw.toUpperCase(); //just for being sure you're doing it right - if (easterEggKeysBuffer.contains(word)) - { - //trace('YOOO! ' + word); - if (FlxG.save.data.psychDevsEasterEgg == word) - FlxG.save.data.psychDevsEasterEgg = ''; - else - FlxG.save.data.psychDevsEasterEgg = word; - FlxG.save.flush(); - - FlxG.sound.play(Paths.sound('ToggleJingle')); - - var black:FlxSprite = new FlxSprite(0, 0).makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - black.alpha = 0; - add(black); - - FlxTween.tween(black, {alpha: 1}, 1, {onComplete: - function(twn:FlxTween) { - FlxTransitionableState.skipNextTransIn = true; - FlxTransitionableState.skipNextTransOut = true; - MusicBeatState.switchState(new TitleState()); - } - }); - FlxG.sound.music.fadeOut(); - if(FreeplayState.vocals != null) - { - FreeplayState.vocals.fadeOut(); - } - closedState = true; - transitioning = true; - playJingle = true; - easterEggKeysBuffer = ''; - break; - } - } - } - } - #end - } - - if (initialized && pressedEnter && !skippedIntro) - { - skipIntro(); - } - - if(swagShader != null) - { - if(controls.UI_LEFT) swagShader.hue -= elapsed * 0.1; - if(controls.UI_RIGHT) swagShader.hue += elapsed * 0.1; - } - - super.update(elapsed); - } - - function createCoolText(textArray:Array, ?offset:Float = 0) - { - for (i in 0...textArray.length) - { - var money:Alphabet = new Alphabet(0, 0, textArray[i], true); - money.screenCenter(X); - money.y += (i * 60) + 200 + offset; - if(credGroup != null && textGroup != null) { - credGroup.add(money); - textGroup.add(money); - } - } - } - - function addMoreText(text:String, ?offset:Float = 0) - { - if(textGroup != null && credGroup != null) { - var coolText:Alphabet = new Alphabet(0, 0, text, true); - coolText.screenCenter(X); - coolText.y += (textGroup.length * 60) + 200 + offset; - credGroup.add(coolText); - textGroup.add(coolText); - } - } - - function deleteCoolText() - { - while (textGroup.members.length > 0) - { - credGroup.remove(textGroup.members[0], true); - textGroup.remove(textGroup.members[0], true); - } - } - - private var sickBeats:Int = 0; //Basically curBeat but won't be skipped if you hold the tab or resize the screen - public static var closedState:Bool = false; - override function beatHit() - { - super.beatHit(); - - if(logoBl != null) - logoBl.animation.play('bump', true); - - if(gfDance != null) { - danceLeft = !danceLeft; - if (danceLeft) - gfDance.animation.play('danceRight'); - else - gfDance.animation.play('danceLeft'); - } - - if(!closedState) { - sickBeats++; - switch (sickBeats) - { - case 1: - //FlxG.sound.music.stop(); - FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic), 0); - FlxG.sound.music.fadeIn(4, 0, 0.7); - case 2: - #if PSYCH_WATERMARKS - createCoolText(['Psych Engine by'], 15); - #else - createCoolText(['ninjamuffin99', 'phantomArcade', 'kawaisprite', 'evilsk8er']); - #end - // credTextShit.visible = true; - case 4: - #if PSYCH_WATERMARKS - addMoreText('Shadow Mario', 15); - addMoreText('RiverOaken', 15); - addMoreText('shubs', 15); - addMoreText('Jordan Santiago', 15); - #else - addMoreText('present'); - #end - // credTextShit.text += '\npresent...'; - // credTextShit.addText(); - case 5: - deleteCoolText(); - // credTextShit.visible = false; - // credTextShit.text = 'In association \nwith'; - // credTextShit.screenCenter(); - case 6: - #if PSYCH_WATERMARKS - createCoolText(['Not associated', 'with'], -40); - #else - createCoolText(['In association', 'with'], -40); - #end - case 8: - addMoreText('newgrounds', -40); - ngSpr.visible = true; - // credTextShit.text += '\nNewgrounds & GitHub'; - case 9: - deleteCoolText(); - ngSpr.visible = false; - // credTextShit.visible = false; - - // credTextShit.text = 'Shoutouts Tom Fulp'; - // credTextShit.screenCenter(); - case 10: - createCoolText([curWacky[0]]); - // credTextShit.visible = true; - case 12: - addMoreText(curWacky[1]); - // credTextShit.text += '\nlmao'; - case 13: - deleteCoolText(); - // credTextShit.visible = false; - // credTextShit.text = "Friday"; - // credTextShit.screenCenter(); - case 14: - addMoreText('Friday'); - // credTextShit.visible = true; - case 15: - addMoreText('Night'); - // credTextShit.text += '\nNight'; - case 16: - addMoreText('Funkin'); // credTextShit.text += '\nFunkin'; - - case 17: - skipIntro(); - } - } - } - - var skippedIntro:Bool = false; - var increaseVolume:Bool = false; - function skipIntro():Void - { - if (!skippedIntro) - { - FlxTween.tween(logoBl, {y: -100}, 1.4, {ease: FlxEase.expoInOut}); - - logoBl.angle = -4; - - new FlxTimer().start(0.01, function(tmr:FlxTimer) - { - if (logoBl.angle == -4) - FlxTween.angle(logoBl, logoBl.angle, 4, 4, {ease: FlxEase.quartInOut}); - if (logoBl.angle == 4) - FlxTween.angle(logoBl, logoBl.angle, -4, 4, {ease: FlxEase.quartInOut}); - }, 0); - if (playJingle) //Ignore deez - { - var easteregg:String = FlxG.save.data.psychDevsEasterEgg; - if (easteregg == null) easteregg = ''; - easteregg = easteregg.toUpperCase(); - - var sound:FlxSound = null; - switch(easteregg) - { - case 'RIVER': - sound = FlxG.sound.play(Paths.sound('JingleRiver')); - case 'SHUBS': - sound = FlxG.sound.play(Paths.sound('JingleShubs')); - case 'SHADOW': - FlxG.sound.play(Paths.sound('JingleShadow')); - case 'BBPANZU': - sound = FlxG.sound.play(Paths.sound('JingleBB')); - - default: //Go back to normal ugly ass boring GF - remove(ngSpr); - remove(credGroup); - FlxG.camera.flash(FlxColor.WHITE, 2); - skippedIntro = true; - playJingle = false; - - FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic), 0); - FlxG.sound.music.fadeIn(4, 0, 0.7); - return; - } - - transitioning = true; - if(easteregg == 'SHADOW') - { - new FlxTimer().start(3.2, function(tmr:FlxTimer) - { - remove(ngSpr); - remove(credGroup); - FlxG.camera.flash(FlxColor.WHITE, 0.6); - transitioning = false; - }); - } - else - { - remove(ngSpr); - remove(credGroup); - FlxG.camera.flash(FlxColor.WHITE, 3); - sound.onComplete = function() { - FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic), 0); - FlxG.sound.music.fadeIn(4, 0, 0.7); - transitioning = false; - }; - } - playJingle = false; - } - else //Default! Edit this one!! - { - remove(ngSpr); - remove(credGroup); - FlxG.camera.flash(FlxColor.WHITE, 4); - - var easteregg:String = FlxG.save.data.psychDevsEasterEgg; - if (easteregg == null) easteregg = ''; - easteregg = easteregg.toUpperCase(); - #if TITLE_SCREEN_EASTER_EGG - if(easteregg == 'SHADOW') - { - FlxG.sound.music.fadeOut(); - if(FreeplayState.vocals != null) - { - FreeplayState.vocals.fadeOut(); - } - } - #end - } - skippedIntro = true; - } - } -} +package; + +#if desktop +import sys.thread.Thread; +#end +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.FlxState; +import flixel.input.keyboard.FlxKey; +import flixel.addons.display.FlxGridOverlay; +import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; +import flixel.addons.transition.FlxTransitionableState; +import flixel.addons.transition.TransitionData; +import haxe.Json; +import openfl.display.Bitmap; +import openfl.display.BitmapData; +#if MODS_ALLOWED +import sys.FileSystem; +import sys.io.File; +#end +import options.GraphicsSettingsSubState; +//import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.graphics.frames.FlxFrame; +import flixel.group.FlxGroup; +import flixel.input.gamepad.FlxGamepad; +import flixel.math.FlxMath; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.system.FlxSound; +import flixel.system.ui.FlxSoundTray; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import openfl.Assets; + +using StringTools; +typedef TitleData = +{ + + titlex:Float, + titley:Float, + startx:Float, + starty:Float, + gfx:Float, + gfy:Float, + backgroundSprite:String, + bpm:Int +} +class TitleState extends MusicBeatState +{ + public static var muteKeys:Array = [FlxKey.ZERO]; + public static var volumeDownKeys:Array = [FlxKey.NUMPADMINUS, FlxKey.MINUS]; + public static var volumeUpKeys:Array = [FlxKey.NUMPADPLUS, FlxKey.PLUS]; + + public static var initialized:Bool = false; + + var blackScreen:FlxSprite; + var credGroup:FlxGroup; + var credTextShit:Alphabet; + var textGroup:FlxGroup; + var ngSpr:FlxSprite; + + var titleTextColors:Array = [0xFF33FFFF, 0xFF3333CC]; + var titleTextAlphas:Array = [1, .64]; + + var curWacky:Array = []; + + var wackyImage:FlxSprite; + + #if TITLE_SCREEN_EASTER_EGG + var easterEggKeys:Array = [ + 'SHADOW', 'RIVER', 'SHUBS', 'BBPANZU' + ]; + var allowedKeys:String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + var easterEggKeysBuffer:String = ''; + #end + + var mustUpdate:Bool = false; + + public static var titleJSON:TitleData; + + public static var updateVersion:String = ''; + + override public function create():Void + { + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); + + #if android + FlxG.android.preventDefaultKeys = [BACK]; + #end + + MusicBeatState.windowNameSuffix = ""; + + #if LUA_ALLOWED + Paths.pushGlobalMods(); + #end + // Just to load a mod on start up if ya got one. For mods that change the menu music and bg + WeekData.loadTheFirstEnabledMod(); + MusicBeatState.windowNamePrefix = Assets.getText(Paths.txt("windowTitleBase", "preload")); + + //trace(path, FileSystem.exists(path)); + /*#if (polymod && !html5) + if (sys.FileSystem.exists('mods/')) { + var folders:Array = []; + for (file in sys.FileSystem.readDirectory('mods/')) { + var path = haxe.io.Path.join(['mods/', file]); + if (sys.FileSystem.isDirectory(path)) { + folders.push(file); + } + } + if(folders.length > 0) { + polymod.Polymod.init({modRoot: "mods", dirs: folders}); + } + } + #end*/ + + FlxG.game.focusLostFramerate = 60; + FlxG.sound.muteKeys = muteKeys; + FlxG.sound.volumeDownKeys = volumeDownKeys; + FlxG.sound.volumeUpKeys = volumeUpKeys; + FlxG.keys.preventDefaultKeys = [TAB]; + + PlayerSettings.init(); + + curWacky = FlxG.random.getObject(getIntroTextShit()); + + // DEBUG BULLSHIT + + swagShader = new ColorSwap(); + super.create(); + + FlxG.save.bind('funkin', CoolUtil.getSavePath()); + + ClientPrefs.loadPrefs(); + + #if (CHECK_FOR_UPDATES && !android) + if(ClientPrefs.checkForUpdates && !closedState) { + trace('checking for update'); + var http = new haxe.Http("https://raw.githubusercontent.com/JordanSantiagoYT/FNF-PsychEngine-NoBotplayLag/main/version.downloadMe"); + var returnedData:Array = []; + + http.onData = function (data:String) + { + returnedData[0] = data.substring(0, data.indexOf(';')); + returnedData[1] = data.substring(data.indexOf('-'), data.length); + updateVersion = returnedData[0]; + var curVersion:String = MainMenuState.psychEngineJSVersion.trim(); + trace('version online: ' + updateVersion + ', your version: ' + curVersion); + if(updateVersion != curVersion) { + trace('versions arent matching!'); + OutdatedState.currChanges = returnedData[1]; + mustUpdate = true; + } + if(updateVersion == curVersion) { + trace('the versions match!'); + } + } + + http.onError = function (error) { + trace('error: $error'); + } + + http.request(); + } + #end + + Highscore.load(); + + // IGNORE THIS!!! + titleJSON = Json.parse(Paths.getTextFromFile('images/gfDanceTitle.json')); + + #if TITLE_SCREEN_EASTER_EGG + if (FlxG.save.data.psychDevsEasterEgg == null) FlxG.save.data.psychDevsEasterEgg = ''; //Crash prevention + switch(FlxG.save.data.psychDevsEasterEgg.toUpperCase()) + { + case 'SHADOW': + titleJSON.gfx += 210; + titleJSON.gfy += 40; + case 'RIVER': + titleJSON.gfx += 100; + titleJSON.gfy += 20; + case 'SHUBS': + titleJSON.gfx += 160; + titleJSON.gfy -= 10; + case 'BBPANZU': + titleJSON.gfx += 45; + titleJSON.gfy += 100; + } + #end + + if(!initialized) + { + if(FlxG.save.data != null && FlxG.save.data.fullscreen) + { + FlxG.fullscreen = FlxG.save.data.fullscreen; + //trace('LOADED FULLSCREEN SETTING!!'); + } + persistentUpdate = true; + persistentDraw = true; + } + + if (FlxG.save.data.weekCompleted != null) + { + StoryMenuState.weekCompleted = FlxG.save.data.weekCompleted; + } + + FlxG.mouse.visible = false; + #if FREEPLAY + MusicBeatState.switchState(new FreeplayState()); + #elseif CHARTING + MusicBeatState.switchState(new ChartingState()); + #else + if(FlxG.save.data.flashing == null && !FlashingState.leftState) { + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; + MusicBeatState.switchState(new FlashingState()); + } else { + if (initialized) + startIntro(); + else + { + new FlxTimer().start(1, function(tmr:FlxTimer) + { + startIntro(); + }); + } + } + #end + } + + var logoBl:FlxSprite; + var gfDance:FlxSprite; + var danceLeft:Bool = false; + var titleText:FlxSprite; + var swagShader:ColorSwap = null; + + function startIntro() + { + if (!initialized) + { + /*var diamond:FlxGraphic = FlxGraphic.fromClass(GraphicTransTileDiamond); + diamond.persist = true; + diamond.destroyOnNoUse = false; + + FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 1, new FlxPoint(0, -1), {asset: diamond, width: 32, height: 32}, + new FlxRect(-300, -300, FlxG.width * 1.8, FlxG.height * 1.8)); + FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 0.7, new FlxPoint(0, 1), + {asset: diamond, width: 32, height: 32}, new FlxRect(-300, -300, FlxG.width * 1.8, FlxG.height * 1.8)); + + transIn = FlxTransitionableState.defaultTransIn; + transOut = FlxTransitionableState.defaultTransOut;*/ + + // HAD TO MODIFY SOME BACKEND SHIT + // IF THIS PR IS HERE IF ITS ACCEPTED UR GOOD TO GO + // https://github.com/HaxeFlixel/flixel-addons/pull/348 + + // var music:FlxSound = new FlxSound(); + // music.loadStream(Paths.music('freakyMenu')); + // FlxG.sound.list.add(music); + // music.play(); + + if(FlxG.sound.music == null) { + FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic), 0); + } + } + + switch(ClientPrefs.daMenuMusic) + { + case 'Mashup' | 'VS Impostor' | 'VS Nonsense V2' | 'Base Game': + Conductor.changeBPM(titleJSON.bpm); + case 'Dave & Bambi': + Conductor.changeBPM(148); + case 'Dave & Bambi (Old)': + Conductor.changeBPM(150); + case 'DDTO+': + Conductor.changeBPM(120); + } + persistentUpdate = true; + + var bg:FlxSprite = new FlxSprite(); + + if (titleJSON.backgroundSprite != null && titleJSON.backgroundSprite.length > 0 && titleJSON.backgroundSprite != "none"){ + bg.loadGraphic(Paths.image(titleJSON.backgroundSprite)); + }else{ + bg.makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + } + + // bg.antialiasing = ClientPrefs.globalAntialiasing; + // bg.setGraphicSize(Std.int(bg.width * 0.6)); + // bg.updateHitbox(); + add(bg); + + logoBl = new FlxSprite(titleJSON.titlex, titleJSON.titley); + logoBl.frames = Paths.getSparrowAtlas('logoBumpin'); + + logoBl.antialiasing = ClientPrefs.globalAntialiasing; + logoBl.animation.addByPrefix('bump', 'logo bumpin', 24, false); + logoBl.animation.play('bump'); + logoBl.updateHitbox(); + // logoBl.screenCenter(); + // logoBl.color = FlxColor.BLACK; + + swagShader = new ColorSwap(); + gfDance = new FlxSprite(titleJSON.gfx, titleJSON.gfy); + + var easterEgg:String = FlxG.save.data.psychDevsEasterEgg; + if(easterEgg == null) easterEgg = ''; //html5 fix + + switch(easterEgg.toUpperCase()) + { + #if TITLE_SCREEN_EASTER_EGG + case 'SHADOW': + gfDance.frames = Paths.getSparrowAtlas('ShadowBump'); + gfDance.animation.addByPrefix('danceLeft', 'Shadow Title Bump', 24); + gfDance.animation.addByPrefix('danceRight', 'Shadow Title Bump', 24); + case 'RIVER': + gfDance.frames = Paths.getSparrowAtlas('RiverBump'); + gfDance.animation.addByIndices('danceLeft', 'River Title Bump', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + gfDance.animation.addByIndices('danceRight', 'River Title Bump', [29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + case 'SHUBS': + gfDance.frames = Paths.getSparrowAtlas('ShubBump'); + gfDance.animation.addByPrefix('danceLeft', 'Shub Title Bump', 24, false); + gfDance.animation.addByPrefix('danceRight', 'Shub Title Bump', 24, false); + case 'BBPANZU': + gfDance.frames = Paths.getSparrowAtlas('BBBump'); + gfDance.animation.addByIndices('danceLeft', 'BB Title Bump', [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27], "", 24, false); + gfDance.animation.addByIndices('danceRight', 'BB Title Bump', [27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], "", 24, false); + #end + + default: + //EDIT THIS ONE IF YOU'RE MAKING A SOURCE CODE MOD!!!! + //EDIT THIS ONE IF YOU'RE MAKING A SOURCE CODE MOD!!!! + //EDIT THIS ONE IF YOU'RE MAKING A SOURCE CODE MOD!!!! + gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle'); + gfDance.animation.addByIndices('danceLeft', 'gfDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + gfDance.animation.addByIndices('danceRight', 'gfDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + } + gfDance.antialiasing = ClientPrefs.globalAntialiasing; + + add(gfDance); + gfDance.shader = swagShader.shader; + add(logoBl); + logoBl.shader = swagShader.shader; + + titleText = new FlxSprite(titleJSON.startx, titleJSON.starty); + #if (desktop || android && MODS_ALLOWED) + var path = SUtil.getPath() + "mods/" + Paths.currentModDirectory + "/images/titleEnter.png"; + //trace(path, FileSystem.exists(path)); + if (!FileSystem.exists(path)){ + path = SUtil.getPath() + "mods/images/titleEnter.png"; + } + //trace(path, FileSystem.exists(path)); + if (!FileSystem.exists(path)){ + path = SUtil.getPath() + "assets/images/titleEnter.png"; + } + //trace(path, FileSystem.exists(path)); + titleText.frames = FlxAtlasFrames.fromSparrow(BitmapData.fromFile(path),File.getContent(StringTools.replace(path,".png",".xml"))); + #else + + titleText.frames = Paths.getSparrowAtlas('titleEnter'); + #end + var animFrames:Array = []; + @:privateAccess { + titleText.animation.findByPrefix(animFrames, "ENTER IDLE"); + titleText.animation.findByPrefix(animFrames, "ENTER FREEZE"); + } + + if (animFrames.length > 0) { + newTitle = true; + + titleText.animation.addByPrefix('idle', "ENTER IDLE", 24); + titleText.animation.addByPrefix('press', ClientPrefs.flashing ? "ENTER PRESSED" : "ENTER FREEZE", 24); + } + else { + newTitle = false; + + titleText.animation.addByPrefix('idle', "Press Enter to Begin", 24); + titleText.animation.addByPrefix('press', "ENTER PRESSED", 24); + } + + titleText.antialiasing = ClientPrefs.globalAntialiasing; + titleText.animation.play('idle'); + titleText.updateHitbox(); + // titleText.screenCenter(X); + add(titleText); + + var logo:FlxSprite = new FlxSprite().loadGraphic(Paths.image('logo')); + logo.screenCenter(); + logo.antialiasing = ClientPrefs.globalAntialiasing; + // add(logo); + + // FlxTween.tween(logoBl, {y: logoBl.y + 50}, 0.6, {ease: FlxEase.quadInOut, type: PINGPONG}); + // FlxTween.tween(logo, {y: logoBl.y + 50}, 0.6, {ease: FlxEase.quadInOut, type: PINGPONG, startDelay: 0.1}); + + credGroup = new FlxGroup(); + add(credGroup); + textGroup = new FlxGroup(); + + blackScreen = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + credGroup.add(blackScreen); + + credTextShit = new Alphabet(0, 0, "", true); + credTextShit.screenCenter(); + + // credTextShit.alignment = CENTER; + + credTextShit.visible = false; + + ngSpr = new FlxSprite(0, FlxG.height * 0.52).loadGraphic(Paths.image('newgrounds_logo')); + add(ngSpr); + ngSpr.visible = false; + ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.8)); + ngSpr.updateHitbox(); + ngSpr.screenCenter(X); + ngSpr.antialiasing = ClientPrefs.globalAntialiasing; + + FlxTween.tween(credTextShit, {y: credTextShit.y + 20}, 2.9, {ease: FlxEase.quadInOut, type: PINGPONG}); + + if (initialized) + skipIntro(); + else + initialized = true; + + // credGroup.add(credTextShit); + } + + function getIntroTextShit():Array> + { + var fullText:String = Assets.getText(Paths.txt('introText')); + + var firstArray:Array = fullText.split('\n'); + var swagGoodArray:Array> = []; + + for (i in firstArray) + { + swagGoodArray.push(i.split('--')); + } + + return swagGoodArray; + } + + var transitioning:Bool = false; + private static var playJingle:Bool = false; + + var newTitle:Bool = false; + var titleTimer:Float = 0; + + override function update(elapsed:Float) + { + if (FlxG.sound.music != null) + Conductor.songPosition = FlxG.sound.music.time; + // FlxG.watch.addQuick('amp', FlxG.sound.music.amplitude); + + var pressedEnter:Bool = FlxG.keys.justPressed.ENTER || controls.ACCEPT; + + #if android + for (touch in FlxG.touches.list) { + if (touch.justPressed) { + pressedEnter = true; + } + } + #end + + var gamepad:FlxGamepad = FlxG.gamepads.lastActive; + + if (gamepad != null) + { + if (gamepad.justPressed.START) + pressedEnter = true; + + #if switch + if (gamepad.justPressed.B) + pressedEnter = true; + #end + } + + if (newTitle) { + titleTimer += CoolUtil.boundTo(elapsed, 0, 1); + if (titleTimer > 2) titleTimer -= 2; + } + + // EASTER EGG + + if (initialized && !transitioning && skippedIntro) + { + if (newTitle && !pressedEnter) + { + var timer:Float = titleTimer; + if (timer >= 1) + timer = (-timer) + 2; + + timer = FlxEase.quadInOut(timer); + + titleText.color = FlxColor.interpolate(titleTextColors[0], titleTextColors[1], timer); + titleText.alpha = FlxMath.lerp(titleTextAlphas[0], titleTextAlphas[1], timer); + } + + if(pressedEnter) + { + titleText.color = FlxColor.WHITE; + titleText.alpha = 1; + + if(titleText != null) titleText.animation.play('press'); + + FlxG.camera.flash(ClientPrefs.flashing ? FlxColor.WHITE : 0x4CFFFFFF, 1); + FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); + + transitioning = true; + // FlxG.sound.music.stop(); + + new FlxTimer().start(1, function(tmr:FlxTimer) + { + if (mustUpdate) { + MusicBeatState.switchState(new OutdatedState()); + } else { + MusicBeatState.switchState(new MainMenuState()); + } + closedState = true; + }); + // FlxG.sound.play(Paths.music('titleShoot'), 0.7); + } + #if TITLE_SCREEN_EASTER_EGG + else if (FlxG.keys.firstJustPressed() != FlxKey.NONE) + { + var keyPressed:FlxKey = FlxG.keys.firstJustPressed(); + var keyName:String = Std.string(keyPressed); + if(allowedKeys.contains(keyName)) { + easterEggKeysBuffer += keyName; + if(easterEggKeysBuffer.length >= 32) easterEggKeysBuffer = easterEggKeysBuffer.substring(1); + //trace('Test! Allowed Key pressed!!! Buffer: ' + easterEggKeysBuffer); + + for (wordRaw in easterEggKeys) + { + var word:String = wordRaw.toUpperCase(); //just for being sure you're doing it right + if (easterEggKeysBuffer.contains(word)) + { + //trace('YOOO! ' + word); + if (FlxG.save.data.psychDevsEasterEgg == word) + FlxG.save.data.psychDevsEasterEgg = ''; + else + FlxG.save.data.psychDevsEasterEgg = word; + FlxG.save.flush(); + + FlxG.sound.play(Paths.sound('ToggleJingle')); + + var black:FlxSprite = new FlxSprite(0, 0).makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + black.alpha = 0; + add(black); + + FlxTween.tween(black, {alpha: 1}, 1, {onComplete: + function(twn:FlxTween) { + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; + MusicBeatState.switchState(new TitleState()); + } + }); + FlxG.sound.music.fadeOut(); + if(FreeplayState.vocals != null) + { + FreeplayState.vocals.fadeOut(); + } + closedState = true; + transitioning = true; + playJingle = true; + easterEggKeysBuffer = ''; + break; + } + } + } + } + #end + } + + if (initialized && pressedEnter && !skippedIntro) + { + skipIntro(); + } + + if(swagShader != null) + { + if(controls.UI_LEFT) swagShader.hue -= elapsed * 0.1; + if(controls.UI_RIGHT) swagShader.hue += elapsed * 0.1; + } + + super.update(elapsed); + } + + function createCoolText(textArray:Array, ?offset:Float = 0) + { + for (i in 0...textArray.length) + { + var money:Alphabet = new Alphabet(0, 0, textArray[i], true); + money.screenCenter(X); + money.y += (i * 60) + 200 + offset; + if(credGroup != null && textGroup != null) { + credGroup.add(money); + textGroup.add(money); + } + } + } + + function addMoreText(text:String, ?offset:Float = 0) + { + if(textGroup != null && credGroup != null) { + var coolText:Alphabet = new Alphabet(0, 0, text, true); + coolText.screenCenter(X); + coolText.y += (textGroup.length * 60) + 200 + offset; + credGroup.add(coolText); + textGroup.add(coolText); + } + } + + function deleteCoolText() + { + while (textGroup.members.length > 0) + { + credGroup.remove(textGroup.members[0], true); + textGroup.remove(textGroup.members[0], true); + } + } + + private var sickBeats:Int = 0; //Basically curBeat but won't be skipped if you hold the tab or resize the screen + public static var closedState:Bool = false; + override function beatHit() + { + super.beatHit(); + + if(logoBl != null) + logoBl.animation.play('bump', true); + + if(gfDance != null) { + danceLeft = !danceLeft; + if (danceLeft) + gfDance.animation.play('danceRight'); + else + gfDance.animation.play('danceLeft'); + } + + if(!closedState) { + sickBeats++; + switch (sickBeats) + { + case 1: + //FlxG.sound.music.stop(); + FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic), 0); + FlxG.sound.music.fadeIn(4, 0, 0.7); + case 2: + #if PSYCH_WATERMARKS + createCoolText(['Psych Engine by'], 15); + #else + createCoolText(['ninjamuffin99', 'phantomArcade', 'kawaisprite', 'evilsk8er']); + #end + // credTextShit.visible = true; + case 4: + #if PSYCH_WATERMARKS + addMoreText('Shadow Mario', 15); + addMoreText('RiverOaken', 15); + addMoreText('shubs', 15); + addMoreText('Jordan Santiago', 15); + #else + addMoreText('present'); + #end + // credTextShit.text += '\npresent...'; + // credTextShit.addText(); + case 5: + deleteCoolText(); + // credTextShit.visible = false; + // credTextShit.text = 'In association \nwith'; + // credTextShit.screenCenter(); + case 6: + #if PSYCH_WATERMARKS + createCoolText(['Not associated', 'with'], -40); + #else + createCoolText(['In association', 'with'], -40); + #end + case 8: + addMoreText('newgrounds', -40); + ngSpr.visible = true; + // credTextShit.text += '\nNewgrounds & GitHub'; + case 9: + deleteCoolText(); + ngSpr.visible = false; + // credTextShit.visible = false; + + // credTextShit.text = 'Shoutouts Tom Fulp'; + // credTextShit.screenCenter(); + case 10: + createCoolText([curWacky[0]]); + // credTextShit.visible = true; + case 12: + addMoreText(curWacky[1]); + // credTextShit.text += '\nlmao'; + case 13: + deleteCoolText(); + // credTextShit.visible = false; + // credTextShit.text = "Friday"; + // credTextShit.screenCenter(); + case 14: + addMoreText('Friday'); + // credTextShit.visible = true; + case 15: + addMoreText('Night'); + // credTextShit.text += '\nNight'; + case 16: + addMoreText('Funkin'); // credTextShit.text += '\nFunkin'; + + case 17: + skipIntro(); + } + } + } + + var skippedIntro:Bool = false; + var increaseVolume:Bool = false; + function skipIntro():Void + { + if (!skippedIntro) + { + FlxTween.tween(logoBl, {y: -100}, 1.4, {ease: FlxEase.expoInOut}); + + logoBl.angle = -4; + + new FlxTimer().start(0.01, function(tmr:FlxTimer) + { + if (logoBl.angle == -4) + FlxTween.angle(logoBl, logoBl.angle, 4, 4, {ease: FlxEase.quartInOut}); + if (logoBl.angle == 4) + FlxTween.angle(logoBl, logoBl.angle, -4, 4, {ease: FlxEase.quartInOut}); + }, 0); + if (playJingle) //Ignore deez + { + var easteregg:String = FlxG.save.data.psychDevsEasterEgg; + if (easteregg == null) easteregg = ''; + easteregg = easteregg.toUpperCase(); + + var sound:FlxSound = null; + switch(easteregg) + { + case 'RIVER': + sound = FlxG.sound.play(Paths.sound('JingleRiver')); + case 'SHUBS': + sound = FlxG.sound.play(Paths.sound('JingleShubs')); + case 'SHADOW': + FlxG.sound.play(Paths.sound('JingleShadow')); + case 'BBPANZU': + sound = FlxG.sound.play(Paths.sound('JingleBB')); + + default: //Go back to normal ugly ass boring GF + remove(ngSpr); + remove(credGroup); + FlxG.camera.flash(FlxColor.WHITE, 2); + skippedIntro = true; + playJingle = false; + + FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic), 0); + FlxG.sound.music.fadeIn(4, 0, 0.7); + return; + } + + transitioning = true; + if(easteregg == 'SHADOW') + { + new FlxTimer().start(3.2, function(tmr:FlxTimer) + { + remove(ngSpr); + remove(credGroup); + FlxG.camera.flash(FlxColor.WHITE, 0.6); + transitioning = false; + }); + } + else + { + remove(ngSpr); + remove(credGroup); + FlxG.camera.flash(FlxColor.WHITE, 3); + sound.onComplete = function() { + FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic), 0); + FlxG.sound.music.fadeIn(4, 0, 0.7); + transitioning = false; + }; + } + playJingle = false; + } + else //Default! Edit this one!! + { + remove(ngSpr); + remove(credGroup); + FlxG.camera.flash(FlxColor.WHITE, 4); + + var easteregg:String = FlxG.save.data.psychDevsEasterEgg; + if (easteregg == null) easteregg = ''; + easteregg = easteregg.toUpperCase(); + #if TITLE_SCREEN_EASTER_EGG + if(easteregg == 'SHADOW') + { + FlxG.sound.music.fadeOut(); + if(FreeplayState.vocals != null) + { + FreeplayState.vocals.fadeOut(); + } + } + #end + } + skippedIntro = true; + } + } +}