diff --git a/source/Caching.hx b/source/Caching.hx new file mode 100644 index 0000000..2c6fb50 --- /dev/null +++ b/source/Caching.hx @@ -0,0 +1,128 @@ +package; + +import haxe.Exception; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import sys.FileSystem; +import sys.io.File; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; +import flixel.addons.transition.FlxTransitionableState; +import flixel.addons.transition.TransitionData; +import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import flixel.text.FlxText; + +using StringTools; + +class Caching extends MusicBeatState +{ + var toBeDone = 0; + var done = 0; + + var text:FlxText; + var kadeLogo:FlxSprite; + + override function create() + { + FlxG.mouse.visible = false; + + FlxG.worldBounds.set(0,0); + + text = new FlxText(FlxG.width / 2, FlxG.height / 2 + 300,0,"Loading..."); + text.size = 34; + text.alignment = FlxTextAlign.CENTER; + text.alpha = 0; + + kadeLogo = new FlxSprite(FlxG.width / 2, FlxG.height / 2).loadGraphic(Paths.image('KadeEngineLogo')); + kadeLogo.x -= kadeLogo.width / 2; + kadeLogo.y -= kadeLogo.height / 2 + 100; + text.y -= kadeLogo.height / 2 - 125; + text.x -= 170; + kadeLogo.setGraphicSize(Std.int(kadeLogo.width * 0.6)); + + kadeLogo.alpha = 0; + + add(kadeLogo); + add(text); + + trace('starting caching..'); + + sys.thread.Thread.create(() -> { + cache(); + }); + + + super.create(); + } + + var calledDone = false; + + override function update(elapsed) + { + + if (toBeDone != 0 && done != toBeDone) + { + var alpha = HelperFunctions.truncateFloat(done / toBeDone * 100,2) / 100; + kadeLogo.alpha = alpha; + text.alpha = alpha; + text.text = "Loading... (" + done + "/" + toBeDone + ")"; + } + + super.update(elapsed); + } + + + function cache() + { + + var images = []; + var music = []; + + trace("caching images..."); + + for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/shared/images/characters"))) + { + if (!i.endsWith(".png")) + continue; + images.push(i); + } + + trace("caching music..."); + + for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/songs"))) + { + music.push(i); + } + + toBeDone = Lambda.count(images) + Lambda.count(music); + + trace("LOADING: " + toBeDone + " OBJECTS."); + + for (i in images) + { + var replaced = i.replace(".png",""); + FlxG.bitmap.add(Paths.image("characters/" + replaced,"shared")); + trace("cached " + replaced); + done++; + } + + for (i in music) + { + FlxG.sound.cache(Paths.inst(i)); + FlxG.sound.cache(Paths.voices(i)); + trace("cached " + i); + done++; + } + + trace("Finished caching..."); + + FlxG.switchState(new TitleState()); + } + +} \ No newline at end of file diff --git a/source/ChartingState.hx b/source/ChartingState.hx index 8e959f9..4371fad 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -1239,7 +1239,7 @@ class ChartingState extends MusicBeatState var daStrumTime = i[0]; var daSus = i[2]; - var note:Note = new Note(daStrumTime, daNoteInfo % 4); + var note:Note = new Note(daStrumTime, daNoteInfo % 4,null,false,true); note.sustainLength = daSus; note.setGraphicSize(GRID_SIZE, GRID_SIZE); note.updateHitbox(); diff --git a/source/Controls.hx b/source/Controls.hx index 7a187ea..ac44eed 100644 --- a/source/Controls.hx +++ b/source/Controls.hx @@ -571,6 +571,7 @@ class Controls extends FlxActionSet //trace(FlxKey.fromString(FlxG.save.data.upBind)); removeKeyboard(); + KeyBinds.keyCheck(); inline bindKeys(Control.UP, [FlxKey.fromString(FlxG.save.data.upBind), FlxKey.UP]); inline bindKeys(Control.DOWN, [FlxKey.fromString(FlxG.save.data.downBind), FlxKey.DOWN]); diff --git a/source/CoolUtil.hx b/source/CoolUtil.hx index 92cc2c0..24dc749 100644 --- a/source/CoolUtil.hx +++ b/source/CoolUtil.hx @@ -6,11 +6,11 @@ using StringTools; class CoolUtil { - public static var difficultyArray:Array = ['EASY', "NORMAL", "HARD"]; + public static var difficultyArray:Array = ['Easy', "Normal", "Hard"]; - public static function difficultyString():String + public static function difficultyFromInt(difficulty:Int):String { - return difficultyArray[PlayState.storyDifficulty]; + return difficultyArray[difficulty]; } public static function coolTextFile(path:String):Array diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index c330edc..daf04fb 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -26,9 +26,11 @@ class FreeplayState extends MusicBeatState var curDifficulty:Int = 1; var scoreText:FlxText; + var comboText:FlxText; var diffText:FlxText; var lerpScore:Int = 0; var intendedScore:Int = 0; + var combo:String = ''; private var grpSongs:FlxTypedGroup; private var curPlaying:Bool = false; @@ -106,6 +108,10 @@ class FreeplayState extends MusicBeatState diffText.font = scoreText.font; add(diffText); + comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24); + comboText.font = diffText.font; + add(comboText); + add(scoreText); changeSelection(); @@ -176,6 +182,7 @@ class FreeplayState extends MusicBeatState lerpScore = intendedScore; scoreText.text = "PERSONAL BEST:" + lerpScore; + comboText.text = combo + '\n'; var upP = controls.UP_P; var downP = controls.DOWN_P; @@ -202,13 +209,20 @@ class FreeplayState extends MusicBeatState if (accepted) { - trace(StringTools.replace(songs[curSelected].songName," ", "-").toLowerCase()); + // adjusting the song name to be compatible + var songFormat = StringTools.replace(songs[curSelected].songName, " ", "-"); + switch (songFormat) { + case 'Dad-Battle': songFormat = 'Dadbattle'; + case 'Philly-Nice': songFormat = 'Philly'; + } + + trace(songs[curSelected].songName); - var poop:String = Highscore.formatSong(StringTools.replace(songs[curSelected].songName," ", "-").toLowerCase(), curDifficulty); + var poop:String = Highscore.formatSong(songFormat, curDifficulty); trace(poop); - - PlayState.SONG = Song.loadFromJson(poop, StringTools.replace(songs[curSelected].songName," ", "-").toLowerCase()); + + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName); PlayState.isStoryMode = false; PlayState.storyDifficulty = curDifficulty; PlayState.storyWeek = songs[curSelected].week; @@ -226,19 +240,19 @@ class FreeplayState extends MusicBeatState if (curDifficulty > 2) curDifficulty = 0; + // adjusting the highscore song name to be compatible (changeDiff) + var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-"); + switch (songHighscore) { + case 'Dad-Battle': songHighscore = 'Dadbattle'; + case 'Philly-Nice': songHighscore = 'Philly'; + } + #if !switch - intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + intendedScore = Highscore.getScore(songHighscore, curDifficulty); + combo = Highscore.getCombo(songHighscore, curDifficulty); #end - switch (curDifficulty) - { - case 0: - diffText.text = "EASY"; - case 1: - diffText.text = 'NORMAL'; - case 2: - diffText.text = "HARD"; - } + diffText.text = CoolUtil.difficultyFromInt(curDifficulty).toUpperCase(); } function changeSelection(change:Int = 0) @@ -258,9 +272,18 @@ class FreeplayState extends MusicBeatState curSelected = 0; // selector.y = (70 * curSelected) + 30; + + // adjusting the highscore song name to be compatible (changeSelection) + // would read original scores if we didn't change packages + var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-"); + switch (songHighscore) { + case 'Dad-Battle': songHighscore = 'Dadbattle'; + case 'Philly-Nice': songHighscore = 'Philly'; + } #if !switch - intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + intendedScore = Highscore.getScore(songHighscore, curDifficulty); + combo = Highscore.getCombo(songHighscore, curDifficulty); // lerpScore = 0; #end diff --git a/source/GameDimensions.hx b/source/GameDimensions.hx new file mode 100644 index 0000000..db4a62a --- /dev/null +++ b/source/GameDimensions.hx @@ -0,0 +1,7 @@ +package; + +class GameDimensions +{ + public static var width:Int = 1280; + public static var height:Int = 720; +} \ No newline at end of file diff --git a/source/GlobalVideo.hx b/source/GlobalVideo.hx new file mode 100644 index 0000000..2c4f707 --- /dev/null +++ b/source/GlobalVideo.hx @@ -0,0 +1,95 @@ +package; + +import openfl.Lib; + +class GlobalVideo +{ + private static var video:VideoHandler; + private static var webm:WebmHandler; + public static var isWebm:Bool = false; + public static var isAndroid:Bool = false; + public static var daAlpha1:Float = 0.2; + public static var daAlpha2:Float = 1; + + public static function setVid(vid:VideoHandler):Void + { + video = vid; + } + + public static function getVid():VideoHandler + { + return video; + } + + public static function setWebm(vid:WebmHandler):Void + { + webm = vid; + isWebm = true; + } + + public static function getWebm():WebmHandler + { + return webm; + } + + public static function get():Dynamic + { + if (isWebm) + { + return getWebm(); + } else { + return getVid(); + } + } + + public static function calc(ind:Int):Dynamic + { + var stageWidth:Int = Lib.current.stage.stageWidth; + var stageHeight:Int = Lib.current.stage.stageHeight; + + var width:Float = GameDimensions.width; + var height:Float = GameDimensions.height; + + //trace("AH: " + stageWidth); + //trace(width); + + var ratioX:Float = height / width; + var ratioY:Float = width / height; + var appliedWidth:Float = stageHeight * ratioY; + var appliedHeight:Float = stageWidth * ratioX; + //trace(appliedWidth); + var remainingX:Float = stageWidth - appliedWidth; + var remainingY:Float = stageHeight - appliedHeight; + remainingX = remainingX / 2; + remainingY = remainingY / 2; + + appliedWidth = Std.int(appliedWidth); + appliedHeight = Std.int(appliedHeight); + + if (appliedHeight > stageHeight) + { + remainingY = 0; + appliedHeight = stageHeight; + } + + if (appliedWidth > stageWidth) + { + remainingX = 0; + appliedWidth = stageWidth; + } + + switch(ind) + { + case 0: + return remainingX; + case 1: + return remainingY; + case 2: + return appliedWidth; + case 3: + return appliedHeight; + } + + return null; + } +} \ No newline at end of file diff --git a/source/HelperFunctions.hx b/source/HelperFunctions.hx index 8f6c6fc..b17dc6a 100644 --- a/source/HelperFunctions.hx +++ b/source/HelperFunctions.hx @@ -1,3 +1,5 @@ +import flixel.math.FlxMath; + class HelperFunctions { public static function truncateFloat( number : Float, precision : Int): Float { @@ -6,4 +8,8 @@ class HelperFunctions num = Math.round( num ) / Math.pow(10, precision); return num; } + + public static function GCD(a, b) { + return b == 0 ? FlxMath.absInt(a) : GCD(b, a % b); + } } \ No newline at end of file diff --git a/source/Highscore.hx b/source/Highscore.hx index 78a6d30..8d82fcb 100644 --- a/source/Highscore.hx +++ b/source/Highscore.hx @@ -2,12 +2,15 @@ package; import flixel.FlxG; +using StringTools; class Highscore { #if (haxe >= "4.0.0") public static var songScores:Map = new Map(); + public static var songCombos:Map = new Map(); #else public static var songScores:Map = new Map(); + public static var songCombos:Map = new Map(); #end @@ -32,6 +35,23 @@ class Highscore }else trace('BotPlay detected. Score saving is disabled.'); } + public static function saveCombo(song:String, combo:String, ?diff:Int = 0):Void + { + var daSong:String = formatSong(song, diff); + var finalCombo:String = combo.split(')')[0].replace('(', ''); + + if(!FlxG.save.data.botplay) + { + if (songCombos.exists(daSong)) + { + if (getComboInt(songCombos.get(daSong)) < getComboInt(finalCombo)) + setCombo(daSong, finalCombo); + } + else + setCombo(daSong, finalCombo); + } + } + public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void { @@ -64,6 +84,14 @@ class Highscore FlxG.save.flush(); } + static function setCombo(song:String, combo:String):Void + { + // Reminder that I don't need to format this song, it should come formatted! + songCombos.set(song, combo); + FlxG.save.data.songCombos = songCombos; + FlxG.save.flush(); + } + public static function formatSong(song:String, diff:Int):String { var daSong:String = song; @@ -76,6 +104,23 @@ class Highscore return daSong; } + static function getComboInt(combo:String):Int + { + switch(combo) + { + case 'SDCB': + return 1; + case 'FC': + return 2; + case 'GFC': + return 3; + case 'MFC': + return 4; + default: + return 0; + } + } + public static function getScore(song:String, diff:Int):Int { if (!songScores.exists(formatSong(song, diff))) @@ -84,6 +129,14 @@ class Highscore return songScores.get(formatSong(song, diff)); } + public static function getCombo(song:String, diff:Int):String + { + if (!songCombos.exists(formatSong(song, diff))) + setCombo(formatSong(song, diff), ''); + + return songCombos.get(formatSong(song, diff)); + } + public static function getWeekScore(week:Int, diff:Int):Int { if (!songScores.exists(formatSong('week' + week, diff))) @@ -98,5 +151,9 @@ class Highscore { songScores = FlxG.save.data.songScores; } + if (FlxG.save.data.songCombos != null) + { + songCombos = FlxG.save.data.songCombos; + } } -} \ No newline at end of file +} diff --git a/source/HitGraph.hx b/source/HitGraph.hx new file mode 100644 index 0000000..7b1d383 --- /dev/null +++ b/source/HitGraph.hx @@ -0,0 +1,279 @@ +import flixel.FlxG; +import openfl.display.Bitmap; +import openfl.display.BitmapData; +import openfl.text.TextFieldAutoSize; +import flixel.system.FlxAssets; +import openfl.text.TextFormat; +import flash.display.Graphics; +import flash.display.Shape; +import flash.display.Sprite; +import flash.text.TextField; +import flash.text.TextFormatAlign; +import flixel.math.FlxMath; +import flixel.util.FlxColor; +import flixel.util.FlxDestroyUtil; + +/** + * stolen from https://github.com/HaxeFlixel/flixel/blob/master/flixel/system/debug/stats/StatsGraph.hx + */ +class HitGraph extends Sprite +{ + static inline var AXIS_COLOR:FlxColor = 0xffffff; + static inline var AXIS_ALPHA:Float = 0.5; + inline static var HISTORY_MAX:Int = 30; + + public var minLabel:TextField; + public var curLabel:TextField; + public var maxLabel:TextField; + public var avgLabel:TextField; + + public var minValue:Float = -(Math.floor((PlayState.rep.replay.sf / 60) * 1000) + 95); + public var maxValue:Float = Math.floor((PlayState.rep.replay.sf / 60) * 1000) + 95; + + public var showInput:Bool = FlxG.save.data.inputShow; + + public var graphColor:FlxColor; + + public var history:Array = []; + + public var bitmap:Bitmap; + + var _axis:Shape; + var _width:Int; + var _height:Int; + var _unit:String; + var _labelWidth:Int; + var _label:String; + + public function new(X:Int, Y:Int, Width:Int, Height:Int) + { + super(); + x = X; + y = Y; + _width = Width; + _height = Height; + + var bm = new BitmapData(Width,Height); + bm.draw(this); + bitmap = new Bitmap(bm); + + _axis = new Shape(); + _axis.x = _labelWidth + 10; + + var ts = Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166; + + var early = createTextField(10,10,FlxColor.WHITE,12); + var late = createTextField(10,_height - 20,FlxColor.WHITE,12); + + early.text = "Early (" + -166 * ts + "ms)"; + late.text = "Late (" + 166 * ts + "ms)"; + + addChild(early); + addChild(late); + + addChild(_axis); + + drawAxes(); + } + + /** + * Redraws the axes of the graph. + */ + function drawAxes():Void + { + var gfx = _axis.graphics; + gfx.clear(); + gfx.lineStyle(1, AXIS_COLOR, AXIS_ALPHA); + + // y-Axis + gfx.moveTo(0, 0); + gfx.lineTo(0, _height); + + // x-Axis + gfx.moveTo(0, _height); + gfx.lineTo(_width, _height); + + gfx.moveTo(0, _height / 2); + gfx.lineTo(_width, _height / 2); + + } + + public static function createTextField(X:Float = 0, Y:Float = 0, Color:FlxColor = FlxColor.WHITE, Size:Int = 12):TextField + { + return initTextField(new TextField(), X, Y, Color, Size); + } + + public static function initTextField(tf:T, X:Float = 0, Y:Float = 0, Color:FlxColor = FlxColor.WHITE, Size:Int = 12):T + { + tf.x = X; + tf.y = Y; + tf.multiline = false; + tf.wordWrap = false; + tf.embedFonts = true; + tf.selectable = false; + #if flash + tf.antiAliasType = AntiAliasType.NORMAL; + tf.gridFitType = GridFitType.PIXEL; + #end + tf.defaultTextFormat = new TextFormat("assets/fonts/vcr.ttf", Size, Color.to24Bit()); + tf.alpha = Color.alphaFloat; + tf.autoSize = TextFieldAutoSize.LEFT; + return tf; + } + + function drawJudgementLine(ms:Float):Void + { + + var gfx:Graphics = graphics; + + gfx.lineStyle(1, graphColor, 0.3); + + var ts = Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166; + var range:Float = Math.max(maxValue - minValue, maxValue * 0.1); + + var value = ((ms * ts) - minValue) / range; + + var pointY = _axis.y + ((-value * _height - 1) + _height); + + var graphX = _axis.x + 1; + + if (ms == 45) + gfx.moveTo(graphX, _axis.y + pointY); + + var graphX = _axis.x + 1; + + gfx.drawRect(graphX,pointY, _width,1); + + gfx.lineStyle(1, graphColor, 1); + } + + /** + * Redraws the graph based on the values stored in the history. + */ + function drawGraph():Void + { + var gfx:Graphics = graphics; + gfx.clear(); + gfx.lineStyle(1, graphColor, 1); + + gfx.beginFill(0x00FF00); + drawJudgementLine(45); + gfx.endFill(); + + gfx.beginFill(0xFF0000); + drawJudgementLine(90); + gfx.endFill(); + + gfx.beginFill(0x8b0000); + drawJudgementLine(135); + gfx.endFill(); + + gfx.beginFill(0x580000); + drawJudgementLine(166); + gfx.endFill(); + + gfx.beginFill(0x00FF00); + drawJudgementLine(-45); + gfx.endFill(); + + gfx.beginFill(0xFF0000); + drawJudgementLine(-90); + gfx.endFill(); + + gfx.beginFill(0x8b0000); + drawJudgementLine(-135); + gfx.endFill(); + + gfx.beginFill(0x580000); + drawJudgementLine(-166); + gfx.endFill(); + + var range:Float = Math.max(maxValue - minValue, maxValue * 0.1); + var graphX = _axis.x + 1; + + if (showInput) + { + for (i in 0...PlayState.rep.replay.ana.anaArray.length) + { + var ana = PlayState.rep.replay.ana.anaArray[i]; + + var value = (ana.key * 25 - minValue) / range; + + if (ana.hit) + gfx.beginFill(0xFFFF00); + else + gfx.beginFill(0xC2B280); + + if (ana.hitTime < 0) + continue; + + var pointY = (-value * _height - 1) + _height; + gfx.drawRect(graphX + fitX(ana.hitTime), pointY,2,2); + gfx.endFill(); + } + } + + for (i in 0...history.length) + { + var value = (history[i][0] - minValue) / range; + var judge = history[i][1]; + + switch(judge) + { + case "sick": + gfx.beginFill(0x00FFFF); + case "good": + gfx.beginFill(0x00FF00); + case "bad": + gfx.beginFill(0xFF0000); + case "shit": + gfx.beginFill(0x8b0000); + case "miss": + gfx.beginFill(0x580000); + default: + gfx.beginFill(0xFFFFFF); + } + var pointY = (-value * _height - 1) + _height; + + /*if (i == 0) + gfx.moveTo(graphX, _axis.y + pointY);*/ + gfx.drawRect(graphX + fitX(history[i][2]), pointY,4,4); + + gfx.endFill(); + } + + + var bm = new BitmapData(_width,_height); + bm.draw(this); + bitmap = new Bitmap(bm); + } + + public function fitX(x:Float) + { + return (x / FlxG.sound.music.length) * width; + } + + public function addToHistory(diff:Float, judge:String, time:Float) + { + history.push([diff,judge, time]); + } + + public function update():Void + { + drawGraph(); + } + + public function average():Float + { + var sum:Float = 0; + for (value in history) + sum += value; + return sum / history.length; + } + + public function destroy():Void + { + _axis = FlxDestroyUtil.removeChild(this, _axis); + history = null; + } +} \ No newline at end of file diff --git a/source/KadeEngineData.hx b/source/KadeEngineData.hx index 5ae671a..f69fb5f 100644 --- a/source/KadeEngineData.hx +++ b/source/KadeEngineData.hx @@ -81,6 +81,15 @@ class KadeEngineData if (FlxG.save.data.customStrumLine == null) FlxG.save.data.customStrumLine = 0; + if (FlxG.save.data.camzoom == null) + FlxG.save.data.camzoom = true; + + if (FlxG.save.data.scoreScreen == null) + FlxG.save.data.scoreScreen = true; + + if (FlxG.save.data.inputShow == null) + FlxG.save.data.inputShow = false; + Conductor.recalculateTimings(); PlayerSettings.player1.controls.loadKeyBinds(); KeyBinds.keyCheck(); diff --git a/source/LoadReplayState.hx b/source/LoadReplayState.hx index 1be8679..3560888 100644 --- a/source/LoadReplayState.hx +++ b/source/LoadReplayState.hx @@ -54,7 +54,7 @@ class LoadReplayState extends MusicBeatState var string:String = controlsStrings[i]; actualNames[i] = string; var rep:Replay = Replay.LoadReplay(string); - controlsStrings[i] = string.split("time")[0] + " " + (rep.replay.songDiff == 2 ? "HARD" : rep.replay.songDiff == 1 ? "EASY" : "NORMAL"); + controlsStrings[i] = string.split("time")[0] + " " + CoolUtil.difficultyFromInt(rep.replay.songDiff).toUpperCase(); } if (controlsStrings.length == 0) @@ -80,7 +80,7 @@ class LoadReplayState extends MusicBeatState } - versionShit = new FlxText(5, FlxG.height - 34, 0, "Replay Loader (ESCAPE TO GO BACK)\nNOTICE!!!! Replays are in a beta stage, and they are probably not 100% correct. expect misses and other stuff that isn't there!", 12); + versionShit = new FlxText(5, FlxG.height - 34, 0, "Replay Loader (ESCAPE TO GO BACK)\nNOTICE!!!! Replays are in a beta stage, and they are probably not 100% correct. expect misses and other stuff that isn't there!\n", 12); versionShit.scrollFactor.set(); versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); add(versionShit); @@ -102,7 +102,7 @@ class LoadReplayState extends MusicBeatState for (i in 0...songs.length) { var pog:FreeplayState.SongMetadata = songs[i]; - if (pog.songName.toLowerCase() == songName) + if (pog.songName == songName) week = pog.week; } return week; @@ -148,13 +148,32 @@ class LoadReplayState extends MusicBeatState PlayState.loadRep = true; - var poop:String = Highscore.formatSong(PlayState.rep.replay.songName.toLowerCase(), PlayState.rep.replay.songDiff); + if (PlayState.rep.replay.replayGameVer == Replay.version) + { - PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName.toLowerCase()); - PlayState.isStoryMode = false; - PlayState.storyDifficulty = PlayState.rep.replay.songDiff; - PlayState.storyWeek = getWeekNumbFromSong(PlayState.rep.replay.songName); - LoadingState.loadAndSwitchState(new PlayState()); + // adjusting the song name to be compatible + var songFormat = StringTools.replace(PlayState.rep.replay.songName, " ", "-"); + switch (songFormat) { + case 'Dad-Battle': songFormat = 'Dadbattle'; + case 'Philly-Nice': songFormat = 'Philly'; + // Replay v1.0 support + case 'dad-battle': songFormat = 'Dadbattle'; + case 'philly-nice': songFormat = 'Philly'; + } + + var poop:String = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff); + + PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName); + PlayState.isStoryMode = false; + PlayState.storyDifficulty = PlayState.rep.replay.songDiff; + PlayState.storyWeek = getWeekNumbFromSong(PlayState.rep.replay.songName); + LoadingState.loadAndSwitchState(new PlayState()); + } + else + { + PlayState.rep = null; + PlayState.loadRep = false; + } } } @@ -177,7 +196,7 @@ class LoadReplayState extends MusicBeatState var rep:Replay = Replay.LoadReplay(actualNames[curSelected]); - poggerDetails.text = "Replay Details - \nDate Created: " + rep.replay.timestamp + "\nSong: " + rep.replay.songName + "\nReplay Version: " + (rep.replay.replayGameVer != Replay.version ? "OUTDATED" : "Latest"); + poggerDetails.text = "Replay Details - \nDate Created: " + rep.replay.timestamp + "\nSong: " + rep.replay.songName + "\nReplay Version: " + rep.replay.replayGameVer + ' (' + (rep.replay.replayGameVer != Replay.version ? "OUTDATED not useable!" : "Latest") + ')\n'; // selector.y = (70 * curSelected) + 30; diff --git a/source/Main.hx b/source/Main.hx index 48f0fc3..6efcae3 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -1,5 +1,7 @@ package; + +import webm.WebmPlayer; import openfl.display.BlendMode; import openfl.text.TextFormat; import openfl.display.Application; @@ -49,6 +51,8 @@ class Main extends Sprite } } + public static var webmHandler:WebmHandler; + private function init(?E:Event):Void { if (hasEventListener(Event.ADDED_TO_STAGE)) @@ -73,14 +77,12 @@ class Main extends Sprite gameHeight = Math.ceil(stageHeight / zoom); } - #if !debug - initialState = TitleState; - #end - + initialState = Caching; + game = new FlxGame(gameWidth, gameHeight, initialState, zoom, framerate, framerate, skipSplash, startFullscreen); addChild(game); - + #if !mobile fpsCounter = new FPS(10, 3, 0xFFFFFF); addChild(fpsCounter); diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index 976f5b3..f2c5d67 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -39,7 +39,7 @@ class MainMenuState extends MusicBeatState public static var nightly:String = ""; - public static var kadeEngineVer:String = "1.5.1" + nightly; + public static var kadeEngineVer:String = "1.5.3" + nightly; public static var gameVer:String = "0.2.7.1"; var magenta:FlxSprite; @@ -165,7 +165,7 @@ class MainMenuState extends MusicBeatState { if (optionShit[curSelected] == 'donate') { - fancyOpenURL("https://www.kickstarter.com/projects/funkin/friday-night-funkin-the-full-ass-game"); + fancyOpenURL("https://ninja-muffin24.itch.io/funkin"); } else { diff --git a/source/ModchartState.hx b/source/ModchartState.hx index c5e3ca3..6e194d1 100644 --- a/source/ModchartState.hx +++ b/source/ModchartState.hx @@ -1,6 +1,7 @@ // this file is for modchart things, this is to declutter playstate.hx // Lua +import openfl.display3D.textures.VideoTexture; import flixel.graphics.FlxGraphic; import flixel.graphics.frames.FlxAtlasFrames; #if windows @@ -255,11 +256,18 @@ class ModchartState function makeAnimatedLuaSprite(spritePath:String,names:Array,prefixes:Array,startAnim:String, id:String) { #if sys - var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + PlayState.SONG.song.toLowerCase() + '/' + spritePath + ".png"); + // pre lowercasing the song name (makeAnimatedLuaSprite) + var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + } + + var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + songLowercase + '/' + spritePath + ".png"); var sprite:FlxSprite = new FlxSprite(0,0); - sprite.frames = FlxAtlasFrames.fromSparrow(FlxGraphic.fromBitmapData(data), Sys.getCwd() + "assets/data/" + PlayState.SONG.song.toLowerCase() + "/" + spritePath + ".xml"); + sprite.frames = FlxAtlasFrames.fromSparrow(FlxGraphic.fromBitmapData(data), Sys.getCwd() + "assets/data/" + songLowercase + "/" + spritePath + ".xml"); trace(sprite.frames.frames.length); @@ -282,7 +290,14 @@ class ModchartState function makeLuaSprite(spritePath:String,toBeCalled:String, drawBehind:Bool) { #if sys - var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + PlayState.SONG.song.toLowerCase() + '/' + spritePath + ".png"); + // pre lowercasing the song name (makeLuaSprite) + var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + } + + var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + songLowercase + '/' + spritePath + ".png"); var sprite:FlxSprite = new FlxSprite(0,0); var imgWidth:Float = FlxG.width / data.width; @@ -345,7 +360,14 @@ class ModchartState //shaders = new Array(); - var result = LuaL.dofile(lua, Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart")); // execute le file + // pre lowercasing the song name (new) + var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + } + + var result = LuaL.dofile(lua, Paths.lua(songLowercase + "/modchart")); // execute le file if (result != 0) { @@ -361,6 +383,8 @@ class ModchartState setVar("scrollspeed", FlxG.save.data.scrollSpeed != 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed); setVar("fpsCap", FlxG.save.data.fpsCap); setVar("downscroll", FlxG.save.data.downscroll); + setVar("flashing", FlxG.save.data.flashing); + setVar("distractions", FlxG.save.data.distractions); setVar("curStep", 0); setVar("curBeat", 0); @@ -413,10 +437,43 @@ class ModchartState PlayState.instance.removeObject(sprite); return true; }); - - // hud/camera + + Lua_helper.add_callback(lua,"initBackgroundVideo", function(videoName:String) { + trace('playing assets/videos/' + videoName + '.webm'); + PlayState.instance.backgroundVideo("assets/videos/" + videoName + ".webm"); + }); + + Lua_helper.add_callback(lua,"pauseVideo", function() { + if (!GlobalVideo.get().paused) + GlobalVideo.get().pause(); + }); + + Lua_helper.add_callback(lua,"resumeVideo", function() { + if (GlobalVideo.get().paused) + GlobalVideo.get().pause(); + }); + + Lua_helper.add_callback(lua,"restartVideo", function() { + GlobalVideo.get().restart(); + }); + + Lua_helper.add_callback(lua,"getVideoSpriteX", function() { + return PlayState.instance.videoSprite.x; + }); + + Lua_helper.add_callback(lua,"getVideoSpriteY", function() { + return PlayState.instance.videoSprite.y; + }); + + Lua_helper.add_callback(lua,"setVideoSpritePos", function(x:Int,y:Int) { + PlayState.instance.videoSprite.setPosition(x,y); + }); + + Lua_helper.add_callback(lua,"setVideoSpriteScale", function(scale:Float) { + PlayState.instance.videoSprite.setGraphicSize(Std.int(PlayState.instance.videoSprite.width * scale)); + }); Lua_helper.add_callback(lua,"setHudAngle", function (x:Float) { PlayState.instance.camHUD.angle = x; @@ -564,6 +621,18 @@ class ModchartState getActorByName(id).x = x; }); + Lua_helper.add_callback(lua,"setActorAccelerationX", function(x:Int,id:String) { + getActorByName(id).acceleration.x = x; + }); + + Lua_helper.add_callback(lua,"setActorDragX", function(x:Int,id:String) { + getActorByName(id).drag.x = x; + }); + + Lua_helper.add_callback(lua,"setActorVelocityX", function(x:Int,id:String) { + getActorByName(id).velocity.x = x; + }); + Lua_helper.add_callback(lua,"playActorAnimation", function(id:String,anim:String,force:Bool = false,reverse:Bool = false) { getActorByName(id).playAnim(anim, force, reverse); }); @@ -575,7 +644,19 @@ class ModchartState Lua_helper.add_callback(lua,"setActorY", function(y:Int,id:String) { getActorByName(id).y = y; }); - + + Lua_helper.add_callback(lua,"setActorAccelerationY", function(y:Int,id:String) { + getActorByName(id).acceleration.y = y; + }); + + Lua_helper.add_callback(lua,"setActorDragY", function(y:Int,id:String) { + getActorByName(id).drag.y = y; + }); + + Lua_helper.add_callback(lua,"setActorVelocityY", function(y:Int,id:String) { + getActorByName(id).velocity.y = y; + }); + Lua_helper.add_callback(lua,"setActorAngle", function(angle:Int,id:String) { getActorByName(id).angle = angle; }); diff --git a/source/Note.hx b/source/Note.hx index 7e29d7b..cdb9cb2 100644 --- a/source/Note.hx +++ b/source/Note.hx @@ -37,7 +37,7 @@ class Note extends FlxSprite public var rating:String = "shit"; - public function new(strumTime:Float, noteData:Int, ?prevNote:Note, ?sustainNote:Bool = false) + public function new(strumTime:Float, noteData:Int, ?prevNote:Note, ?sustainNote:Bool = false, ?inCharter:Bool = false) { super(); @@ -50,7 +50,10 @@ class Note extends FlxSprite x += 50; // MAKE SURE ITS DEFINITELY OFF SCREEN? y -= 2000; - this.strumTime = strumTime; + if (inCharter) + this.strumTime = strumTime; + else + this.strumTime = Math.round(strumTime); if (this.strumTime < 0 ) this.strumTime = 0; @@ -59,7 +62,14 @@ class Note extends FlxSprite var daStage:String = PlayState.curStage; - switch (PlayState.SONG.noteStyle) + //defaults if no noteStyle was found in chart + var noteTypeCheck:String = 'normal'; + + if (PlayState.SONG.noteStyle == null) { + switch(PlayState.storyWeek) {case 6: noteTypeCheck = 'pixel';} + } else {noteTypeCheck = PlayState.SONG.noteStyle;} + + switch (noteTypeCheck) { case 'pixel': loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels','week6'), true, 17, 17); diff --git a/source/OFLSprite.hx b/source/OFLSprite.hx new file mode 100644 index 0000000..abea3a0 --- /dev/null +++ b/source/OFLSprite.hx @@ -0,0 +1,39 @@ +import flixel.util.FlxColor; +import openfl.display.Sprite; +import flixel.FlxSprite; + +/** + * designed to draw a Open FL Sprite as a FlxSprite (to allow layering and auto sizing for haxe flixel cameras) + * Custom made for Kade Engine + */ +class OFLSprite extends FlxSprite +{ + public var flSprite:Sprite; + + public function new(x,y,width,height,Sprite:Sprite) + { + super(x,y); + + makeGraphic(width,height,FlxColor.TRANSPARENT); + + flSprite = Sprite; + + pixels.draw(flSprite); + } + + private var _frameCount:Int = 0; + + override function update(elapsed:Float) + { + if (_frameCount != 2) + { + pixels.draw(flSprite); + _frameCount++; + } + } + + public function updateDisplay() + { + pixels.draw(flSprite); + } +} \ No newline at end of file diff --git a/source/Options.hx b/source/Options.hx index 1d6208c..c763b2c 100644 --- a/source/Options.hx +++ b/source/Options.hx @@ -261,6 +261,27 @@ class FlashingLightsOption extends Option } } +class ShowInput extends Option +{ + public function new(desc:String) + { + super(); + description = desc; + } + public override function press():Bool + { + FlxG.save.data.inputShow = !FlxG.save.data.inputShow; + display = updateDisplay(); + return true; + } + + private override function updateDisplay():String + { + return (FlxG.save.data.inputShow ? "Extended Score Info" : "Minimalized Info"); + } +} + + class Judgement extends Option { @@ -296,8 +317,8 @@ class Judgement extends Option override function getValue():String { return "Safe Frames: " + Conductor.safeFrames + - " - SIK: " + HelperFunctions.truncateFloat(45 * Conductor.timeScale, 0) + - "ms GD: " + HelperFunctions.truncateFloat(90 * Conductor.timeScale, 0) + + " - SIK: " + HelperFunctions.truncateFloat(22 * Conductor.timeScale, 0) + + "ms GD: " + HelperFunctions.truncateFloat(45 * Conductor.timeScale, 0) + "ms BD: " + HelperFunctions.truncateFloat(135 * Conductor.timeScale, 0) + "ms SHT: " + HelperFunctions.truncateFloat(155 * Conductor.timeScale, 0) + "ms TOTAL: " + HelperFunctions.truncateFloat(Conductor.safeZoneOffset,0) + "ms"; @@ -338,6 +359,27 @@ class FPSOption extends Option } } +class ScoreScreen extends Option +{ + public function new(desc:String) + { + super(); + description = desc; + } + + public override function press():Bool + { + FlxG.save.data.scoreScreen = !FlxG.save.data.scoreScreen; + return true; + } + + private override function updateDisplay():String + { + return (FlxG.save.data.scoreScreen ? "Show Score Screen" : "No Score Screen"); + } +} + + class FPSCapOption extends Option @@ -614,3 +656,23 @@ class BotPlay extends Option private override function updateDisplay():String return "BotPlay " + (FlxG.save.data.botplay ? "on" : "off"); } + +class CamZoomOption extends Option +{ + public function new(desc:String) + { + super(); + description = desc; + } + public override function press():Bool + { + FlxG.save.data.camzoom = !FlxG.save.data.camzoom; + display = updateDisplay(); + return true; + } + + private override function updateDisplay():String + { + return "Camera Zoom " + (!FlxG.save.data.camzoom ? "off" : "on"); + } +} diff --git a/source/OptionsMenu.hx b/source/OptionsMenu.hx index 9d690e7..a79ade3 100644 --- a/source/OptionsMenu.hx +++ b/source/OptionsMenu.hx @@ -39,15 +39,14 @@ class OptionsMenu extends MusicBeatState new CustomizeGameplay("Drag'n'Drop Gameplay Modules around to your preference") ]), new OptionCategory("Appearance", [ - #if desktop new DistractionsAndEffectsOption("Toggle stage distractions that can hinder your gameplay."), + new CamZoomOption("Toggle the camera zoom in-game."), + #if desktop new RainbowFPSOption("Make the FPS Counter Rainbow"), new AccuracyOption("Display accuracy information."), new NPSDisplayOption("Shows your current Notes Per Second."), new SongPositionOption("Show the songs current position (as a bar)"), new CpuStrums("CPU's strumline lights up when a note hits it."), - #else - new DistractionsAndEffectsOption("Toggle stage distractions that can hinder your gameplay.") #end ]), @@ -58,7 +57,9 @@ class OptionsMenu extends MusicBeatState #end new FlashingLightsOption("Toggle flashing lights that can cause epileptic seizures and strain."), new WatermarkOption("Enable and disable all watermarks from the engine."), - new BotPlay("Showcase your charts and mods with autoplay.") + new BotPlay("Showcase your charts and mods with autoplay."), + new ScoreScreen("Show the score screen after the end of a song"), + new ShowInput("Display every single input in the score screen.") ]) ]; @@ -130,14 +131,17 @@ class OptionsMenu extends MusicBeatState isCat = false; grpControls.clear(); for (i in 0...options.length) - { - var controlLabel:Alphabet = new Alphabet(0, (70 * i) + 30, options[i].getName(), true, false); - controlLabel.isMenuItem = true; - controlLabel.targetY = i; - grpControls.add(controlLabel); - // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! - } + { + var controlLabel:Alphabet = new Alphabet(0, (70 * i) + 30, options[i].getName(), true, false); + controlLabel.isMenuItem = true; + controlLabel.targetY = i; + grpControls.add(controlLabel); + // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! + } + curSelected = 0; + + changeSelection(curSelected); } if (controls.UP_P) changeSelection(-1); @@ -146,7 +150,6 @@ class OptionsMenu extends MusicBeatState if (isCat) { - if (currentSelectedCat.getOptions()[curSelected].getAccept()) { if (FlxG.keys.pressed.SHIFT) @@ -166,7 +169,6 @@ class OptionsMenu extends MusicBeatState } else { - if (FlxG.keys.pressed.SHIFT) { if (FlxG.keys.justPressed.RIGHT) @@ -179,7 +181,7 @@ class OptionsMenu extends MusicBeatState else if (FlxG.keys.pressed.LEFT) FlxG.save.data.offset -= 0.1; - + versionShit.text = "Offset (Left, Right, Shift for slow): " + HelperFunctions.truncateFloat(FlxG.save.data.offset,2) + " - Description - " + currentDescription; } if (currentSelectedCat.getOptions()[curSelected].getAccept()) versionShit.text = currentSelectedCat.getOptions()[curSelected].getValue() + " - Description - " + currentDescription; @@ -189,16 +191,18 @@ class OptionsMenu extends MusicBeatState else { if (FlxG.keys.pressed.SHIFT) - { - if (FlxG.keys.justPressed.RIGHT) - FlxG.save.data.offset += 0.1; - else if (FlxG.keys.justPressed.LEFT) - FlxG.save.data.offset -= 0.1; - } - else if (FlxG.keys.pressed.RIGHT) + { + if (FlxG.keys.justPressed.RIGHT) FlxG.save.data.offset += 0.1; - else if (FlxG.keys.pressed.LEFT) + else if (FlxG.keys.justPressed.LEFT) FlxG.save.data.offset -= 0.1; + } + else if (FlxG.keys.pressed.RIGHT) + FlxG.save.data.offset += 0.1; + else if (FlxG.keys.pressed.LEFT) + FlxG.save.data.offset -= 0.1; + + versionShit.text = "Offset (Left, Right, Shift for slow): " + HelperFunctions.truncateFloat(FlxG.save.data.offset,2) + " - Description - " + currentDescription; } @@ -231,6 +235,8 @@ class OptionsMenu extends MusicBeatState } curSelected = 0; } + + changeSelection(curSelected); } } FlxG.save.flush(); diff --git a/source/Paths.hx b/source/Paths.hx index 27cd3e4..075adbd 100644 --- a/source/Paths.hx +++ b/source/Paths.hx @@ -97,14 +97,22 @@ class Paths inline static public function voices(song:String) { - song = StringTools.replace(song," ", "-"); - return 'songs:assets/songs/${song.toLowerCase()}/Voices.$SOUND_EXT'; + var songLowercase = StringTools.replace(song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + } + return 'songs:assets/songs/${songLowercase}/Voices.$SOUND_EXT'; } inline static public function inst(song:String) { - song = StringTools.replace(song," ", "-"); - return 'songs:assets/songs/${song.toLowerCase()}/Inst.$SOUND_EXT'; + var songLowercase = StringTools.replace(song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + } + return 'songs:assets/songs/${songLowercase}/Inst.$SOUND_EXT'; } inline static public function image(key:String, ?library:String) diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx index e59e72b..3985d4b 100644 --- a/source/PauseSubState.hx +++ b/source/PauseSubState.hx @@ -33,6 +33,13 @@ class PauseSubState extends MusicBeatSubstate { super(); + if (PlayState.instance.useVideo) + { + menuItems.remove("Resume"); + if (GlobalVideo.get().playing) + GlobalVideo.get().pause(); + } + pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true); pauseMusic.volume = 0; pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2))); @@ -52,7 +59,7 @@ class PauseSubState extends MusicBeatSubstate add(levelInfo); var levelDifficulty:FlxText = new FlxText(20, 15 + 32, 0, "", 32); - levelDifficulty.text += CoolUtil.difficultyString(); + levelDifficulty.text += CoolUtil.difficultyFromInt(PlayState.storyDifficulty).toUpperCase(); levelDifficulty.scrollFactor.set(); levelDifficulty.setFormat(Paths.font('vcr.ttf'), 32); levelDifficulty.updateHitbox(); @@ -98,13 +105,23 @@ class PauseSubState extends MusicBeatSubstate super.update(elapsed); + if (PlayState.instance.useVideo) + menuItems.remove('Resume'); + var upP = controls.UP_P; var downP = controls.DOWN_P; var leftP = controls.LEFT_P; var rightP = controls.RIGHT_P; var accepted = controls.ACCEPT; var oldOffset:Float = 0; - var songPath = 'assets/data/' + PlayState.SONG.song.toLowerCase() + '/'; + + // pre lowercasing the song name (update) + var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + } + var songPath = 'assets/data/' + songLowercase + '/'; if (upP) { @@ -180,8 +197,20 @@ class PauseSubState extends MusicBeatSubstate case "Resume": close(); case "Restart Song": + if (PlayState.instance.useVideo) + { + GlobalVideo.get().stop(); + PlayState.instance.remove(PlayState.instance.videoSprite); + PlayState.instance.removedVideo = true; + } FlxG.resetState(); case "Exit to menu": + if (PlayState.instance.useVideo) + { + GlobalVideo.get().stop(); + PlayState.instance.remove(PlayState.instance.videoSprite); + PlayState.instance.removedVideo = true; + } if(PlayState.loadRep) { FlxG.save.data.botplay = false; diff --git a/source/PlayState.hx b/source/PlayState.hx index 9c24a1d..949dea2 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -1,5 +1,8 @@ package; +import Replay.Ana; +import Replay.Analysis; +import webm.WebmPlayer; import flixel.input.keyboard.FlxKey; import haxe.Exception; import openfl.geom.Matrix; @@ -75,6 +78,7 @@ class PlayState extends MusicBeatState public static var storyPlaylist:Array = []; public static var storyDifficulty:Int = 1; public static var weekSong:Int = 0; + public static var weekScore:Int = 0; public static var shits:Int = 0; public static var bads:Int = 0; public static var goods:Int = 0; @@ -103,6 +107,8 @@ class PlayState extends MusicBeatState private var vocals:FlxSound; + public var originalX:Float; + public static var dad:Character; public static var gf:Character; public static var boyfriend:Boyfriend; @@ -128,7 +134,8 @@ class PlayState extends MusicBeatState public var health:Float = 1; //making public because sethealth doesnt work without it private var combo:Int = 0; public static var misses:Int = 0; - private var accuracy:Float = 0.00; + public static var campaignMisses:Int = 0; + public var accuracy:Float = 0.00; private var accuracyDefault:Float = 0.00; private var totalNotesHit:Float = 0; private var totalNotesHitDefault:Float = 0; @@ -176,7 +183,7 @@ class PlayState extends MusicBeatState var wiggleShit:WiggleEffect = new WiggleEffect(); var talking:Bool = true; - var songScore:Int = 0; + public var songScore:Int = 0; var songScoreDef:Int = 0; var scoreTxt:FlxText; var replayTxt:FlxText; @@ -206,7 +213,11 @@ class PlayState extends MusicBeatState // BotPlay text private var botPlayState:FlxText; // Replay shit - private var saveNotes:Array = []; + private var saveNotes:Array = []; + private var saveJudge:Array = []; + private var replayAna:Analysis = new Analysis(); // replay analysis + + public static var highestCombo:Int = 0; private var executeModchart = false; @@ -226,36 +237,46 @@ class PlayState extends MusicBeatState if (FlxG.sound.music != null) FlxG.sound.music.stop(); - sicks = 0; - bads = 0; - shits = 0; - goods = 0; - + if (!isStoryMode) + { + sicks = 0; + bads = 0; + shits = 0; + goods = 0; + } misses = 0; repPresses = 0; repReleases = 0; + + PlayStateChangeables.useDownscroll = FlxG.save.data.downscroll; + PlayStateChangeables.safeFrames = FlxG.save.data.frames; + PlayStateChangeables.scrollSpeed = FlxG.save.data.scrollSpeed; + PlayStateChangeables.botPlay = FlxG.save.data.botplay; + + + // pre lowercasing the song name (create) + var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + } + + removedVideo = false; + #if windows - executeModchart = FileSystem.exists(Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart")); + executeModchart = FileSystem.exists(Paths.lua(songLowercase + "/modchart")); #end #if !cpp executeModchart = false; // FORCE disable for non cpp targets #end - trace('Mod chart: ' + executeModchart + " - " + Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart")); + trace('Mod chart: ' + executeModchart + " - " + Paths.lua(songLowercase + "/modchart")); #if windows // Making difficulty text for Discord Rich Presence. - switch (storyDifficulty) - { - case 0: - storyDifficultyText = "Easy"; - case 1: - storyDifficultyText = "Normal"; - case 2: - storyDifficultyText = "Hard"; - } + storyDifficultyText = CoolUtil.difficultyFromInt(storyDifficulty); iconRPC = SONG.player2; @@ -302,15 +323,15 @@ class PlayState extends MusicBeatState persistentDraw = true; if (SONG == null) - SONG = Song.loadFromJson('tutorial'); + SONG = Song.loadFromJson('tutorial', 'tutorial'); Conductor.mapBPMChanges(SONG); Conductor.changeBPM(SONG.bpm); - trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + Conductor.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: ' + Conductor.timeScale + '\nBotPlay : ' + FlxG.save.data.botplay); + trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + PlayStateChangeables.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: ' + Conductor.timeScale + '\nBotPlay : ' + PlayStateChangeables.botPlay); //dialogue shit - switch (SONG.song.toLowerCase()) + switch (songLowercase) { case 'tutorial': dialogue = ["Hey you're pretty cute.", 'Use the arrow keys to keep up \nwith me singing.']; @@ -323,7 +344,7 @@ class PlayState extends MusicBeatState ]; case 'fresh': dialogue = ["Not too shabby boy.", ""]; - case 'dad battle': + case 'dadbattle': dialogue = [ "gah you think you're hot stuff?", "If you can beat me here...", @@ -337,7 +358,22 @@ class PlayState extends MusicBeatState dialogue = CoolUtil.coolTextFile(Paths.txt('thorns/thornsDialogue')); } - switch(SONG.stage) + //defaults if no stage was found in chart + var stageCheck:String = 'stage'; + + if (SONG.stage == null) { + switch(storyWeek) + { + case 2: stageCheck = 'halloween'; + case 3: stageCheck = 'philly'; + case 4: stageCheck = 'limo'; + case 5: if (songLowercase == 'winter-horrorland') {stageCheck = 'mallEvil';} else {stageCheck = 'mall';} + case 6: if (songLowercase == 'thorns') {stageCheck = 'schoolEvil';} else {stageCheck = 'school';} + //i should check if its stage (but this is when none is found in chart anyway) + } + } else {stageCheck = SONG.stage;} + + switch(stageCheck) { case 'halloween': { @@ -592,7 +628,7 @@ class PlayState extends MusicBeatState bgGirls = new BackgroundGirls(-100, 190); bgGirls.scrollFactor.set(0.9, 0.9); - if (SONG.song.toLowerCase() == 'roses') + if (songLowercase == 'roses') { if(FlxG.save.data.distractions){ bgGirls.getScared(); @@ -716,21 +752,33 @@ class PlayState extends MusicBeatState add(stageCurtains); } } - var gfVersion:String = 'gf'; - switch (SONG.gfVersion) + //defaults if no gf was found in chart + var gfCheck:String = 'gf'; + + if (SONG.gfVersion == null) { + switch(storyWeek) + { + case 4: gfCheck = 'gf-car'; + case 5: gfCheck = 'gf-christmas'; + case 6: gfCheck = 'gf-pixel'; + } + } else {gfCheck = SONG.gfVersion;} + + var curGf:String = ''; + switch (gfCheck) { case 'gf-car': - gfVersion = 'gf-car'; + curGf = 'gf-car'; case 'gf-christmas': - gfVersion = 'gf-christmas'; + curGf = 'gf-christmas'; case 'gf-pixel': - gfVersion = 'gf-pixel'; + curGf = 'gf-pixel'; default: - gfVersion = 'gf'; + curGf = 'gf'; } - gf = new Character(400, 130, gfVersion); + gf = new Character(400, 130, curGf); gf.scrollFactor.set(0.95, 0.95); dad = new Character(100, 100, SONG.player2); @@ -830,13 +878,17 @@ class PlayState extends MusicBeatState { FlxG.watch.addQuick('rep rpesses',repPresses); FlxG.watch.addQuick('rep releases',repReleases); - - FlxG.save.data.botplay = true; - FlxG.save.data.scrollSpeed = rep.replay.noteSpeed; - FlxG.save.data.downscroll = rep.replay.isDownscroll; // FlxG.watch.addQuick('Queued',inputsQueued); + + PlayStateChangeables.useDownscroll = rep.replay.isDownscroll; + PlayStateChangeables.safeFrames = rep.replay.sf; + PlayStateChangeables.botPlay = true; } + trace('uh ' + PlayStateChangeables.safeFrames); + + trace("SF CALC: " + Math.floor((PlayStateChangeables.safeFrames / 60) * 1000)); + var doof:DialogueBox = new DialogueBox(false, dialogue); // doof.x += 70; // doof.y = FlxG.height * 0.5; @@ -848,7 +900,7 @@ class PlayState extends MusicBeatState strumLine = new FlxSprite(0, 50).makeGraphic(FlxG.width, 10); strumLine.scrollFactor.set(); - if (FlxG.save.data.downscroll) + if (PlayStateChangeables.useDownscroll) strumLine.y = FlxG.height - 165; strumLineNotes = new FlxTypedGroup(); @@ -894,7 +946,7 @@ class PlayState extends MusicBeatState if (FlxG.save.data.songPosition) // I dont wanna talk about this code :( { songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar')); - if (FlxG.save.data.downscroll) + if (PlayStateChangeables.useDownscroll) songPosBG.y = FlxG.height * 0.9 + 45; songPosBG.screenCenter(X); songPosBG.scrollFactor.set(); @@ -906,8 +958,8 @@ class PlayState extends MusicBeatState songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); add(songPosBar); - var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - 20,songPosBG.y,0,SONG.song, 16); - if (FlxG.save.data.downscroll) + var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - (SONG.song.length * 5),songPosBG.y,0,SONG.song, 16); + if (PlayStateChangeables.useDownscroll) songName.y -= 3; songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); songName.scrollFactor.set(); @@ -916,7 +968,7 @@ class PlayState extends MusicBeatState } healthBarBG = new FlxSprite(0, FlxG.height * 0.9).loadGraphic(Paths.image('healthBar')); - if (FlxG.save.data.downscroll) + if (PlayStateChangeables.useDownscroll) healthBarBG.y = 50; healthBarBG.screenCenter(X); healthBarBG.scrollFactor.set(); @@ -930,37 +982,43 @@ class PlayState extends MusicBeatState add(healthBar); // Add Kade Engine watermark - kadeEngineWatermark = new FlxText(4,healthBarBG.y + 50,0,SONG.song + " " + (storyDifficulty == 2 ? "Hard" : storyDifficulty == 1 ? "Normal" : "Easy") + (Main.watermarks ? " - KE " + MainMenuState.kadeEngineVer : ""), 16); + kadeEngineWatermark = new FlxText(4,healthBarBG.y + 50,0,SONG.song + " " + CoolUtil.difficultyFromInt(storyDifficulty) + (Main.watermarks ? " - KE " + MainMenuState.kadeEngineVer : ""), 16); kadeEngineWatermark.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); kadeEngineWatermark.scrollFactor.set(); add(kadeEngineWatermark); - if (FlxG.save.data.downscroll) + if (PlayStateChangeables.useDownscroll) kadeEngineWatermark.y = FlxG.height * 0.9 + 45; scoreTxt = new FlxText(FlxG.width / 2 - 235, healthBarBG.y + 50, 0, "", 20); - if (!FlxG.save.data.accuracyDisplay) - scoreTxt.x = healthBarBG.x + healthBarBG.width / 2; - scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + + scoreTxt.screenCenter(X); + + originalX = scoreTxt.x; + + scoreTxt.scrollFactor.set(); - if (offsetTesting) - scoreTxt.x += 300; - if(FlxG.save.data.botplay) scoreTxt.x = FlxG.width / 2 - 20; + + scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, FlxTextAlign.CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + add(scoreTxt); - replayTxt = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (FlxG.save.data.downscroll ? 100 : -100), 0, "REPLAY", 20); + replayTxt = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (PlayStateChangeables.useDownscroll ? 100 : -100), 0, "REPLAY", 20); replayTxt.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + replayTxt.borderSize = 4; + replayTxt.borderQuality = 2; replayTxt.scrollFactor.set(); if (loadRep) { add(replayTxt); } // Literally copy-paste of the above, fu - botPlayState = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (FlxG.save.data.downscroll ? 100 : -100), 0, "BOTPLAY", 20); + botPlayState = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (PlayStateChangeables.useDownscroll ? 100 : -100), 0, "BOTPLAY", 20); botPlayState.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); botPlayState.scrollFactor.set(); - - if(FlxG.save.data.botplay && !loadRep) add(botPlayState); + botPlayState.borderSize = 4; + botPlayState.borderQuality = 2; + if(PlayStateChangeables.botPlay && !loadRep) add(botPlayState); iconP1 = new HealthIcon(SONG.player1, true); iconP1.y = healthBar.y - (iconP1.height / 2); @@ -998,7 +1056,7 @@ class PlayState extends MusicBeatState if (isStoryMode) { - switch (curSong.toLowerCase()) + switch (StringTools.replace(curSong," ", "-").toLowerCase()) { case "winter-horrorland": var blackScreen:FlxSprite = new FlxSprite(0, 0).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK); @@ -1071,11 +1129,11 @@ class PlayState extends MusicBeatState senpaiEvil.updateHitbox(); senpaiEvil.screenCenter(); - if (SONG.song.toLowerCase() == 'roses' || SONG.song.toLowerCase() == 'thorns') + if (StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'roses' || StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'thorns') { remove(black); - if (SONG.song.toLowerCase() == 'thorns') + if (StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'thorns') { add(red); } @@ -1095,7 +1153,7 @@ class PlayState extends MusicBeatState { inCutscene = true; - if (SONG.song.toLowerCase() == 'thorns') + if (StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'thorns') { add(senpaiEvil); senpaiEvil.alpha = 0; @@ -1156,10 +1214,16 @@ class PlayState extends MusicBeatState #if windows + // pre lowercasing the song name (startCountdown) + var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + } if (executeModchart) { luaModchart = ModchartState.createModchartState(); - luaModchart.executeState('start',[PlayState.SONG.song]); + luaModchart.executeState('start',[songLowercase]); } #end @@ -1300,7 +1364,7 @@ class PlayState extends MusicBeatState remove(songName); songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar')); - if (FlxG.save.data.downscroll) + if (PlayStateChangeables.useDownscroll) songPosBG.y = FlxG.height * 0.9 + 45; songPosBG.screenCenter(X); songPosBG.scrollFactor.set(); @@ -1313,8 +1377,8 @@ class PlayState extends MusicBeatState songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME); add(songPosBar); - var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - 20,songPosBG.y,0,SONG.song, 16); - if (FlxG.save.data.downscroll) + var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - (SONG.song.length * 5),songPosBG.y,0,SONG.song, 16); + if (PlayStateChangeables.useDownscroll) songName.y -= 3; songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); songName.scrollFactor.set(); @@ -1328,9 +1392,12 @@ class PlayState extends MusicBeatState // Song check real quick switch(curSong) { - case 'Bopeebo' | 'Philly' | 'Blammed' | 'Cocoa' | 'Eggnog': allowedToHeadbang = true; + case 'Bopeebo' | 'Philly Nice' | 'Blammed' | 'Cocoa' | 'Eggnog': allowedToHeadbang = true; default: allowedToHeadbang = false; } + + if (useVideo) + GlobalVideo.get().resume(); #if windows // Updating Discord Rich Presence (with Time Left) @@ -1370,7 +1437,15 @@ class PlayState extends MusicBeatState // Per song offset check #if windows - var songPath = 'assets/data/' + StringTools.replace(PlayState.SONG.song," ", "-").toLowerCase() + '/'; + // pre lowercasing the song name (generateSong) + var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + } + + var songPath = 'assets/data/' + songLowercase + '/'; + for(file in sys.FileSystem.readDirectory(songPath)) { var path = haxe.io.Path.join([songPath, file]); @@ -1471,7 +1546,14 @@ class PlayState extends MusicBeatState // FlxG.log.add(i); var babyArrow:FlxSprite = new FlxSprite(0, strumLine.y); - switch (SONG.noteStyle) + //defaults if no noteStyle was found in chart + var noteTypeCheck:String = 'normal'; + + if (SONG.noteStyle == null) { + switch(storyWeek) {case 6: noteTypeCheck = 'pixel';} + } else {noteTypeCheck = SONG.noteStyle;} + + switch (noteTypeCheck) { case 'pixel': babyArrow.loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17); @@ -1486,16 +1568,6 @@ class PlayState extends MusicBeatState switch (Math.abs(i)) { - case 0: - babyArrow.x += Note.swagWidth * 0; - babyArrow.animation.add('static', [0]); - babyArrow.animation.add('pressed', [4, 8], 12, false); - babyArrow.animation.add('confirm', [12, 16], 24, false); - case 1: - babyArrow.x += Note.swagWidth * 1; - babyArrow.animation.add('static', [1]); - babyArrow.animation.add('pressed', [5, 9], 12, false); - babyArrow.animation.add('confirm', [13, 17], 24, false); case 2: babyArrow.x += Note.swagWidth * 2; babyArrow.animation.add('static', [2]); @@ -1506,75 +1578,85 @@ class PlayState extends MusicBeatState babyArrow.animation.add('static', [3]); babyArrow.animation.add('pressed', [7, 11], 12, false); babyArrow.animation.add('confirm', [15, 19], 24, false); + case 1: + babyArrow.x += Note.swagWidth * 1; + babyArrow.animation.add('static', [1]); + babyArrow.animation.add('pressed', [5, 9], 12, false); + babyArrow.animation.add('confirm', [13, 17], 24, false); + case 0: + babyArrow.x += Note.swagWidth * 0; + babyArrow.animation.add('static', [0]); + babyArrow.animation.add('pressed', [4, 8], 12, false); + babyArrow.animation.add('confirm', [12, 16], 24, false); } - case 'normal': - babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets'); - babyArrow.animation.addByPrefix('green', 'arrowUP'); - babyArrow.animation.addByPrefix('blue', 'arrowDOWN'); - babyArrow.animation.addByPrefix('purple', 'arrowLEFT'); - babyArrow.animation.addByPrefix('red', 'arrowRIGHT'); + case 'normal': + babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets'); + babyArrow.animation.addByPrefix('green', 'arrowUP'); + babyArrow.animation.addByPrefix('blue', 'arrowDOWN'); + babyArrow.animation.addByPrefix('purple', 'arrowLEFT'); + babyArrow.animation.addByPrefix('red', 'arrowRIGHT'); + + babyArrow.antialiasing = true; + babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7)); + + switch (Math.abs(i)) + { + case 0: + babyArrow.x += Note.swagWidth * 0; + babyArrow.animation.addByPrefix('static', 'arrowLEFT'); + babyArrow.animation.addByPrefix('pressed', 'left press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false); + case 1: + babyArrow.x += Note.swagWidth * 1; + babyArrow.animation.addByPrefix('static', 'arrowDOWN'); + babyArrow.animation.addByPrefix('pressed', 'down press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false); + case 2: + babyArrow.x += Note.swagWidth * 2; + babyArrow.animation.addByPrefix('static', 'arrowUP'); + babyArrow.animation.addByPrefix('pressed', 'up press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false); + case 3: + babyArrow.x += Note.swagWidth * 3; + babyArrow.animation.addByPrefix('static', 'arrowRIGHT'); + babyArrow.animation.addByPrefix('pressed', 'right press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false); + } - babyArrow.antialiasing = true; - babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7)); + default: + babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets'); + babyArrow.animation.addByPrefix('green', 'arrowUP'); + babyArrow.animation.addByPrefix('blue', 'arrowDOWN'); + babyArrow.animation.addByPrefix('purple', 'arrowLEFT'); + babyArrow.animation.addByPrefix('red', 'arrowRIGHT'); - switch (Math.abs(i)) - { - case 0: - babyArrow.x += Note.swagWidth * 0; - babyArrow.animation.addByPrefix('static', 'arrowLEFT'); - babyArrow.animation.addByPrefix('pressed', 'left press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false); - case 1: - babyArrow.x += Note.swagWidth * 1; - babyArrow.animation.addByPrefix('static', 'arrowDOWN'); - babyArrow.animation.addByPrefix('pressed', 'down press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false); - case 2: - babyArrow.x += Note.swagWidth * 2; - babyArrow.animation.addByPrefix('static', 'arrowUP'); - babyArrow.animation.addByPrefix('pressed', 'up press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false); - case 3: - babyArrow.x += Note.swagWidth * 3; - babyArrow.animation.addByPrefix('static', 'arrowRIGHT'); - babyArrow.animation.addByPrefix('pressed', 'right press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false); + babyArrow.antialiasing = true; + babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7)); + + switch (Math.abs(i)) + { + case 0: + babyArrow.x += Note.swagWidth * 0; + babyArrow.animation.addByPrefix('static', 'arrowLEFT'); + babyArrow.animation.addByPrefix('pressed', 'left press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false); + case 1: + babyArrow.x += Note.swagWidth * 1; + babyArrow.animation.addByPrefix('static', 'arrowDOWN'); + babyArrow.animation.addByPrefix('pressed', 'down press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false); + case 2: + babyArrow.x += Note.swagWidth * 2; + babyArrow.animation.addByPrefix('static', 'arrowUP'); + babyArrow.animation.addByPrefix('pressed', 'up press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false); + case 3: + babyArrow.x += Note.swagWidth * 3; + babyArrow.animation.addByPrefix('static', 'arrowRIGHT'); + babyArrow.animation.addByPrefix('pressed', 'right press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false); } - - default: - babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets'); - babyArrow.animation.addByPrefix('green', 'arrowUP'); - babyArrow.animation.addByPrefix('blue', 'arrowDOWN'); - babyArrow.animation.addByPrefix('purple', 'arrowLEFT'); - babyArrow.animation.addByPrefix('red', 'arrowRIGHT'); - - babyArrow.antialiasing = true; - babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7)); - - switch (Math.abs(i)) - { - case 0: - babyArrow.x += Note.swagWidth * 0; - babyArrow.animation.addByPrefix('static', 'arrowLEFT'); - babyArrow.animation.addByPrefix('pressed', 'left press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false); - case 1: - babyArrow.x += Note.swagWidth * 1; - babyArrow.animation.addByPrefix('static', 'arrowDOWN'); - babyArrow.animation.addByPrefix('pressed', 'down press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false); - case 2: - babyArrow.x += Note.swagWidth * 2; - babyArrow.animation.addByPrefix('static', 'arrowUP'); - babyArrow.animation.addByPrefix('pressed', 'up press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false); - case 3: - babyArrow.x += Note.swagWidth * 3; - babyArrow.animation.addByPrefix('static', 'arrowRIGHT'); - babyArrow.animation.addByPrefix('pressed', 'right press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false); - } } babyArrow.updateHitbox(); @@ -1686,15 +1768,32 @@ class PlayState extends MusicBeatState public static var songRate = 1.5; + public var stopUpdate = false; + public var removedVideo = false; + override public function update(elapsed:Float) { #if !debug perfectMode = false; #end - if (FlxG.save.data.botplay && FlxG.keys.justPressed.ONE) + if (PlayStateChangeables.botPlay && FlxG.keys.justPressed.ONE) camHUD.visible = !camHUD.visible; + + if (useVideo && GlobalVideo.get() != null && !stopUpdate) + { + if (GlobalVideo.get().ended && !removedVideo) + { + remove(videoSprite); + FlxG.stage.window.onFocusOut.remove(focusOut); + FlxG.stage.window.onFocusIn.remove(focusIn); + removedVideo = true; + } + } + + + #if windows if (executeModchart && luaModchart != null && songStarted) { @@ -1797,8 +1896,10 @@ class PlayState extends MusicBeatState super.update(elapsed); scoreTxt.text = Ratings.CalculateRanking(songScore,songScoreDef,nps,maxNPS,accuracy); - if (!FlxG.save.data.accuracyDisplay) - scoreTxt.text = "Score: " + songScore; + + var lengthInPx = scoreTxt.textField.length * scoreTxt.frameHeight; // bad way but does more or less a better job + + scoreTxt.x = (originalX - (lengthInPx / 2)) + 335; if (FlxG.keys.justPressed.ENTER && startedCountdown && canPause) { @@ -1818,6 +1919,14 @@ class PlayState extends MusicBeatState if (FlxG.keys.justPressed.SEVEN) { + if (useVideo) + { + GlobalVideo.get().stop(); + remove(videoSprite); + FlxG.stage.window.onFocusOut.remove(focusOut); + FlxG.stage.window.onFocusIn.remove(focusIn); + removedVideo = true; + } #if windows DiscordClient.changePresence("Chart Editor", null, null, true); #end @@ -1861,8 +1970,17 @@ class PlayState extends MusicBeatState FlxG.switchState(new Charting()); */ #if debug - if (FlxG.keys.justPressed.EIGHT) + if (FlxG.keys.justPressed.SIX) { + if (useVideo) + { + GlobalVideo.get().stop(); + remove(videoSprite); + FlxG.stage.window.onFocusOut.remove(focusOut); + FlxG.stage.window.onFocusIn.remove(focusIn); + removedVideo = true; + } + FlxG.switchState(new AnimationDebug(SONG.player2)); #if windows if (luaModchart != null) @@ -1935,7 +2053,7 @@ class PlayState extends MusicBeatState // Per song treatment since some songs will only have the 'Hey' at certain times switch(curSong) { - case 'Philly': + case 'Philly Nice': { // General duration of the song if(curBeat < 250) @@ -2210,12 +2328,12 @@ class PlayState extends MusicBeatState if (!daNote.modifiedByLua) { - if (FlxG.save.data.downscroll) + if (PlayStateChangeables.useDownscroll) { if (daNote.mustPress) - daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); + daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2)); else - daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); + daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2)); if(daNote.isSustainNote) { // Remember = minus makes notes go up, plus makes them go down @@ -2225,7 +2343,7 @@ class PlayState extends MusicBeatState daNote.y += daNote.height / 2; // If not in botplay, only clip sustain notes when properly hit, botplay gets to clip it everytime - if(!FlxG.save.data.botplay) + if(!PlayStateChangeables.botPlay) { if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= (strumLine.y + Note.swagWidth / 2)) { @@ -2247,14 +2365,14 @@ class PlayState extends MusicBeatState }else { if (daNote.mustPress) - daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); + daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2)); else - daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2)); + daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2)); if(daNote.isSustainNote) { daNote.y -= daNote.height / 2; - if(!FlxG.save.data.botplay) + if(!PlayStateChangeables.botPlay) { if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y + daNote.offset.y * daNote.scale.y <= (strumLine.y + Note.swagWidth / 2)) { @@ -2366,7 +2484,7 @@ class PlayState extends MusicBeatState // WIP interpolation shit? Need to fix the pause issue // daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed)); - if ((daNote.mustPress && daNote.tooLate && !FlxG.save.data.downscroll || daNote.mustPress && daNote.tooLate && FlxG.save.data.downscroll) && daNote.mustPress) + if ((daNote.mustPress && daNote.tooLate && !PlayStateChangeables.useDownscroll || daNote.mustPress && daNote.tooLate && PlayStateChangeables.useDownscroll) && daNote.mustPress) { if (daNote.isSustainNote && daNote.wasGoodHit) { @@ -2375,10 +2493,26 @@ class PlayState extends MusicBeatState } else { - health -= 0.075; - vocals.volume = 0; - if (theFunne) - noteMiss(daNote.noteData, daNote); + if (loadRep && daNote.isSustainNote) + { + // im tired and lazy this sucks I know i'm dumb + if (findByTime(daNote.strumTime) != null) + totalNotesHit += 1; + else + { + health -= 0.075; + vocals.volume = 0; + if (theFunne) + noteMiss(daNote.noteData, daNote); + } + } + else + { + health -= 0.075; + vocals.volume = 0; + if (theFunne) + noteMiss(daNote.noteData, daNote); + } } daNote.visible = false; @@ -2413,13 +2547,24 @@ class PlayState extends MusicBeatState function endSong():Void { + if (useVideo) + { + GlobalVideo.get().stop(); + FlxG.stage.window.onFocusOut.remove(focusOut); + FlxG.stage.window.onFocusIn.remove(focusIn); + PlayState.instance.remove(PlayState.instance.videoSprite); + } + + if (isStoryMode) + campaignMisses = misses; + if (!loadRep) - rep.SaveReplay(saveNotes); + rep.SaveReplay(saveNotes, saveJudge, replayAna); else { - FlxG.save.data.botplay = false; - FlxG.save.data.scrollSpeed = 1; - FlxG.save.data.downscroll = false; + PlayStateChangeables.botPlay = false; + PlayStateChangeables.scrollSpeed = 1; + PlayStateChangeables.useDownscroll = false; } if (FlxG.save.data.fpsCap > 290) @@ -2436,10 +2581,21 @@ class PlayState extends MusicBeatState canPause = false; FlxG.sound.music.volume = 0; vocals.volume = 0; + FlxG.sound.music.pause(); + vocals.pause(); if (SONG.validScore) { + // adjusting the highscore song name to be compatible + // would read original scores if we didn't change packages + var songHighscore = StringTools.replace(PlayState.SONG.song, " ", "-"); + switch (songHighscore) { + case 'Dad-Battle': songHighscore = 'Dadbattle'; + case 'Philly-Nice': songHighscore = 'Philly'; + } + #if !switch - Highscore.saveScore(SONG.song, Math.round(songScore), storyDifficulty); + Highscore.saveScore(songHighscore, Math.round(songScore), storyDifficulty); + Highscore.saveCombo(songHighscore, Ratings.GenerateLetterRank(accuracy), storyDifficulty); #end } @@ -2460,12 +2616,20 @@ class PlayState extends MusicBeatState if (storyPlaylist.length <= 0) { - FlxG.sound.playMusic(Paths.music('freakyMenu')); - transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; - FlxG.switchState(new StoryMenuState()); + paused = true; + + FlxG.sound.music.stop(); + vocals.stop(); + if (FlxG.save.data.scoreScreen) + openSubState(new ResultsScreen()); + else + { + FlxG.sound.playMusic(Paths.music('freakyMenu')); + FlxG.switchState(new MainMenuState()); + } #if windows if (luaModchart != null) @@ -2489,18 +2653,20 @@ class PlayState extends MusicBeatState } else { - var difficulty:String = ""; + + // adjusting the song name to be compatible + var songFormat = StringTools.replace(PlayState.storyPlaylist[0], " ", "-"); + switch (songFormat) { + case 'Dad-Battle': songFormat = 'Dadbattle'; + case 'Philly-Nice': songFormat = 'Philly'; + } - if (storyDifficulty == 0) - difficulty = '-easy'; - - if (storyDifficulty == 2) - difficulty = '-hard'; + var poop:String = Highscore.formatSong(songFormat, storyDifficulty); trace('LOADING NEXT SONG'); - trace(PlayState.storyPlaylist[0].toLowerCase() + difficulty); + trace(poop); - if (SONG.song.toLowerCase() == 'eggnog') + if (StringTools.replace(PlayState.storyPlaylist[0], " ", "-").toLowerCase() == 'eggnog') { var blackShit:FlxSprite = new FlxSprite(-FlxG.width * FlxG.camera.zoom, -FlxG.height * FlxG.camera.zoom).makeGraphic(FlxG.width * 3, FlxG.height * 3, FlxColor.BLACK); @@ -2515,7 +2681,8 @@ class PlayState extends MusicBeatState FlxTransitionableState.skipNextTransOut = true; prevCamFollow = camFollow; - PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + difficulty, PlayState.storyPlaylist[0]); + + PlayState.SONG = Song.loadFromJson(poop, PlayState.storyPlaylist[0]); FlxG.sound.music.stop(); LoadingState.loadAndSwitchState(new PlayState()); @@ -2524,7 +2691,17 @@ class PlayState extends MusicBeatState else { trace('WENT BACK TO FREEPLAY??'); - FlxG.switchState(new FreeplayState()); + + paused = true; + + + FlxG.sound.music.stop(); + vocals.stop(); + + if (FlxG.save.data.scoreScreen) + openSubState(new ResultsScreen()); + else + FlxG.switchState(new FreeplayState()); } } } @@ -2540,11 +2717,10 @@ class PlayState extends MusicBeatState private function popUpScore(daNote:Note):Void { - var noteDiff:Float = Math.abs(Conductor.songPosition - daNote.strumTime); - var wife:Float = EtternaFunctions.wife3(noteDiff, Conductor.timeScale); + var noteDiff:Float = -(daNote.strumTime - Conductor.songPosition); + 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); @@ -2639,7 +2815,10 @@ class PlayState extends MusicBeatState rating.velocity.x -= FlxG.random.int(0, 10); var msTiming = HelperFunctions.truncateFloat(noteDiff, 3); - if(FlxG.save.data.botplay) msTiming = 0; + if(PlayStateChangeables.botPlay && !loadRep) msTiming = 0; + + if (loadRep) + msTiming = HelperFunctions.truncateFloat(findByTime(daNote.strumTime)[3], 3); if (currentTimingShown != null) remove(currentTimingShown); @@ -2685,7 +2864,7 @@ class PlayState extends MusicBeatState if (currentTimingShown.alpha != 1) currentTimingShown.alpha = 1; - if(!FlxG.save.data.botplay) add(currentTimingShown); + if(!PlayStateChangeables.botPlay || loadRep) add(currentTimingShown); var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); comboSpr.screenCenter(); @@ -2702,7 +2881,7 @@ class PlayState extends MusicBeatState comboSpr.velocity.x += FlxG.random.int(1, 10); currentTimingShown.velocity.x += comboSpr.velocity.x; - if(!FlxG.save.data.botplay) add(rating); + if(!PlayStateChangeables.botPlay || loadRep) add(rating); if (!curStage.startsWith('school')) { @@ -2729,8 +2908,17 @@ class PlayState extends MusicBeatState var comboSplit:Array = (combo + "").split(''); - if (comboSplit.length == 2) - seperatedScore.push(0); // make sure theres a 0 in front or it looks weird lol! + if (combo > highestCombo) + highestCombo = combo; + + // make sure we have 3 digits to display (looks weird otherwise lol) + if (comboSplit.length == 1) + { + seperatedScore.push(0); + seperatedScore.push(0); + } + else if (comboSplit.length == 2) + seperatedScore.push(0); for(i in 0...comboSplit.length) { @@ -2762,8 +2950,7 @@ class PlayState extends MusicBeatState numScore.velocity.y -= FlxG.random.int(140, 160); numScore.velocity.x = FlxG.random.float(-5, 5); - if (combo >= 10 || combo == 0) - add(numScore); + add(numScore); FlxTween.tween(numScore, {alpha: 0}, 0.2, { onComplete: function(tween:FlxTween) @@ -2847,13 +3034,21 @@ class PlayState extends MusicBeatState }; #end + // Prevent player input if botplay is on - if(FlxG.save.data.botplay) + if(PlayStateChangeables.botPlay) { holdArray = [false, false, false, false]; pressArray = [false, false, false, false]; releaseArray = [false, false, false, false]; } + + var anas:Array = [null,null,null,null]; + + for (i in 0...pressArray.length) + if (pressArray[i]) + anas[i] = new Ana(Conductor.songPosition, null, false, "miss", i); + // HOLDS, check for sustain notes if (holdArray.contains(true) && /*!boyfriend.stunned && */ generatedMusic) { @@ -2872,37 +3067,21 @@ class PlayState extends MusicBeatState var possibleNotes:Array = []; // notes that can be hit var directionList:Array = []; // directions that can be hit var dumbNotes:Array = []; // notes to kill later - + var directionsAccounted:Array = [false,false,false,false]; // we don't want to do judgments for more than one presses + notes.forEachAlive(function(daNote:Note) { if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit) { - if (directionList.contains(daNote.noteData)) - { - for (coolNote in possibleNotes) - { - if (coolNote.noteData == daNote.noteData && Math.abs(daNote.strumTime - coolNote.strumTime) < 10) - { // if it's the same note twice at < 10ms distance, just delete it - // EXCEPT u cant delete it in this loop cuz it fucks with the collection lol - dumbNotes.push(daNote); - break; - } - else if (coolNote.noteData == daNote.noteData && daNote.strumTime < coolNote.strumTime) - { // if daNote is earlier than existing note (coolNote), replace - possibleNotes.remove(coolNote); - possibleNotes.push(daNote); - break; - } - } - } - else + if (!directionsAccounted[daNote.noteData]) { + directionsAccounted[daNote.noteData] = true; possibleNotes.push(daNote); directionList.push(daNote.noteData); } } }); - + for (note in dumbNotes) { FlxG.log.add("killing dumb ass note at " + note.strumTime); @@ -2912,18 +3091,10 @@ class PlayState extends MusicBeatState } possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime)); - - var dontCheck = false; - - for (i in 0...pressArray.length) - { - if (pressArray[i] && !directionList.contains(i)) - dontCheck = true; - } if (perfectMode) goodNoteHit(possibleNotes[0]); - else if (possibleNotes.length > 0 && !dontCheck) + else if (possibleNotes.length > 0) { if (!FlxG.save.data.ghost) { @@ -2940,6 +3111,10 @@ class PlayState extends MusicBeatState if (mashViolations != 0) mashViolations--; scoreTxt.color = FlxColor.WHITE; + var noteDiff:Float = -(coolNote.strumTime - Conductor.songPosition); + anas[coolNote.noteData].hit = true; + anas[coolNote.noteData].hitJudge = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000)); + anas[coolNote.noteData].nearestNote = [coolNote.strumTime,coolNote.noteData,coolNote.sustainLength]; goodNoteHit(coolNote); } } @@ -2951,33 +3126,28 @@ class PlayState extends MusicBeatState noteMiss(shit, null); } - if(dontCheck && possibleNotes.length > 0 && FlxG.save.data.ghost && !FlxG.save.data.botplay) - { - if (mashViolations > 8) - { - trace('mash violations ' + mashViolations); - scoreTxt.color = FlxColor.RED; - noteMiss(0,null); - } - else - mashViolations++; - } - } + + if (!loadRep) + for (i in anas) + if (i != null) + replayAna.anaArray.push(i); // put em all there notes.forEachAlive(function(daNote:Note) { - if(FlxG.save.data.downscroll && daNote.y > strumLine.y || - !FlxG.save.data.downscroll && daNote.y < strumLine.y) + if(PlayStateChangeables.useDownscroll && daNote.y > strumLine.y || + !PlayStateChangeables.useDownscroll && daNote.y < strumLine.y) { // Force good note hit regardless if it's too late to hit it or not as a fail safe - if(FlxG.save.data.botplay && daNote.canBeHit && daNote.mustPress || - FlxG.save.data.botplay && daNote.tooLate && daNote.mustPress) + if(PlayStateChangeables.botPlay && daNote.canBeHit && daNote.mustPress || + PlayStateChangeables.botPlay && daNote.tooLate && daNote.mustPress) { if(loadRep) { //trace('ReplayNote ' + tmpRepNote.strumtime + ' | ' + tmpRepNote.direction); - if(rep.replay.songNotes.contains(HelperFunctions.truncateFloat(daNote.strumTime, 2))) + var n = findByTime(daNote.strumTime); + trace(n); + if(n != null) { goodNoteHit(daNote); boyfriend.holdTimer = daNote.sustainLength; @@ -2990,7 +3160,7 @@ class PlayState extends MusicBeatState } }); - if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && (!holdArray.contains(true) || FlxG.save.data.botplay)) + if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && (!holdArray.contains(true) || PlayStateChangeables.botPlay)) { if (boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss')) boyfriend.playAnim('idle'); @@ -3014,6 +3184,112 @@ class PlayState extends MusicBeatState }); } + public function findByTime(time:Float):Array + { + for (i in rep.replay.songNotes) + { + //trace('checking ' + Math.round(i[0]) + ' against ' + Math.round(time)); + if (i[0] == time) + return i; + } + return null; + } + + public function findByTimeIndex(time:Float):Int + { + for (i in 0...rep.replay.songNotes.length) + { + //trace('checking ' + Math.round(i[0]) + ' against ' + Math.round(time)); + if (rep.replay.songNotes[i][0] == time) + return i; + } + return -1; + } + + public var fuckingVolume:Float = 1; + public var useVideo = false; + + public static var webmHandler:WebmHandler; + + public var playingDathing = false; + + public var videoSprite:FlxSprite; + + public function focusOut() { + if (paused) + return; + persistentUpdate = false; + persistentDraw = true; + paused = true; + + if (FlxG.sound.music != null) + { + FlxG.sound.music.pause(); + vocals.pause(); + } + + openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); + } + public function focusIn() + { + // nada + } + + + public function backgroundVideo(source:String) // for background videos + { + useVideo = true; + + FlxG.stage.window.onFocusOut.add(focusOut); + FlxG.stage.window.onFocusIn.add(focusIn); + + var ourSource:String = "assets/videos/daWeirdVid/dontDelete.webm"; + WebmPlayer.SKIP_STEP_LIMIT = 90; + var str1:String = "WEBM SHIT"; + webmHandler = new WebmHandler(); + webmHandler.source(ourSource); + webmHandler.makePlayer(); + webmHandler.webm.name = str1; + + GlobalVideo.setWebm(webmHandler); + + GlobalVideo.get().source(source); + GlobalVideo.get().clearPause(); + if (GlobalVideo.isWebm) + { + GlobalVideo.get().updatePlayer(); + } + GlobalVideo.get().show(); + + if (GlobalVideo.isWebm) + { + GlobalVideo.get().restart(); + } else { + GlobalVideo.get().play(); + } + + var data = webmHandler.webm.bitmapData; + + videoSprite = new FlxSprite(-470,-30).loadGraphic(data); + + videoSprite.setGraphicSize(Std.int(videoSprite.width * 1.2)); + + remove(gf); + remove(boyfriend); + remove(dad); + add(videoSprite); + add(gf); + add(boyfriend); + add(dad); + + trace('poggers'); + + if (!songStarted) + webmHandler.pause(); + else + webmHandler.resume(); + } + function noteMiss(direction:Int = 1, daNote:Note):Void { if (!boyfriend.stunned) @@ -3026,6 +3302,21 @@ class PlayState extends MusicBeatState combo = 0; misses++; + if (daNote != null) + { + if (!loadRep) + { + saveNotes.push([daNote.strumTime,0,direction,166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166]); + saveJudge.push("miss"); + } + } + else + if (!loadRep) + { + saveNotes.push([Conductor.songPosition,0,direction,166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166]); + saveJudge.push("miss"); + } + //var noteDiff:Float = Math.abs(daNote.strumTime - Conductor.songPosition); //var wife:Float = EtternaFunctions.wife3(noteDiff, FlxG.save.data.etternaMode ? 1 : 1.7); @@ -3112,9 +3403,9 @@ class PlayState extends MusicBeatState function noteCheck(controlArray:Array, note:Note):Void // sorry lol { - var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition); + var noteDiff:Float = -(note.strumTime - Conductor.songPosition); - note.rating = Ratings.CalculateRating(noteDiff); + note.rating = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000)); /* if (loadRep) { @@ -3163,9 +3454,18 @@ class PlayState extends MusicBeatState if (mashing != 0) mashing = 0; - var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition); + var noteDiff:Float = -(note.strumTime - Conductor.songPosition); - note.rating = Ratings.CalculateRating(noteDiff); + if(loadRep) + { + noteDiff = findByTime(note.strumTime)[3]; + note.rating = rep.replay.songJudgements[findByTimeIndex(note.strumTime)]; + } + else + note.rating = Ratings.CalculateRating(noteDiff); + + if (note.rating == "miss") + return; // add newest note to front of notesHitArray // the oldest notes are at the end and are removed first @@ -3208,7 +3508,14 @@ class PlayState extends MusicBeatState if(!loadRep && note.mustPress) - saveNotes.push(HelperFunctions.truncateFloat(note.strumTime, 2)); + { + var array = [note.strumTime,note.sustainLength,note.noteData,noteDiff]; + if (note.isSustainNote) + array[1] = -1; + trace('pushing ' + array[0]); + saveNotes.push(array); + saveJudge.push(note.rating); + } playerStrums.forEach(function(spr:FlxSprite) { @@ -3347,8 +3654,6 @@ class PlayState extends MusicBeatState } #end - - // yes this updates every step. // yes this is bad // but i'm doing it to update misses and accuracy @@ -3371,7 +3676,7 @@ class PlayState extends MusicBeatState if (generatedMusic) { - notes.sort(FlxSort.byY, (FlxG.save.data.downscroll ? FlxSort.ASCENDING : FlxSort.DESCENDING)); + notes.sort(FlxSort.byY, (PlayStateChangeables.useDownscroll ? FlxSort.ASCENDING : FlxSort.DESCENDING)); } #if windows @@ -3406,22 +3711,26 @@ class PlayState extends MusicBeatState // FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM); wiggleShit.update(Conductor.crochet); - // HARDCODING FOR MILF ZOOMS! - if (curSong.toLowerCase() == 'milf' && curBeat >= 168 && curBeat < 200 && camZooming && FlxG.camera.zoom < 1.35) + if (FlxG.save.data.camzoom) { - FlxG.camera.zoom += 0.015; - camHUD.zoom += 0.03; - } - - if (camZooming && FlxG.camera.zoom < 1.35 && curBeat % 4 == 0) - { - FlxG.camera.zoom += 0.015; - camHUD.zoom += 0.03; + // HARDCODING FOR MILF ZOOMS! + if (curSong.toLowerCase() == 'milf' && curBeat >= 168 && curBeat < 200 && camZooming && FlxG.camera.zoom < 1.35) + { + FlxG.camera.zoom += 0.015; + camHUD.zoom += 0.03; + } + + if (camZooming && FlxG.camera.zoom < 1.35 && curBeat % 4 == 0) + { + FlxG.camera.zoom += 0.015; + camHUD.zoom += 0.03; + } + } iconP1.setGraphicSize(Std.int(iconP1.width + 30)); iconP2.setGraphicSize(Std.int(iconP2.width + 30)); - + iconP1.updateHitbox(); iconP2.updateHitbox(); diff --git a/source/PlayStateChangeables.hx b/source/PlayStateChangeables.hx new file mode 100644 index 0000000..8ee4995 --- /dev/null +++ b/source/PlayStateChangeables.hx @@ -0,0 +1,7 @@ +class PlayStateChangeables +{ + public static var useDownscroll:Bool; + public static var safeFrames:Int; + public static var scrollSpeed:Float; + public static var botPlay:Bool; +} \ No newline at end of file diff --git a/source/Ratings.hx b/source/Ratings.hx index 615d3ba..758f8bf 100644 --- a/source/Ratings.hx +++ b/source/Ratings.hx @@ -5,7 +5,7 @@ class Ratings public static function GenerateLetterRank(accuracy:Float) // generate a letter ranking { var ranking:String = "N/A"; - if(FlxG.save.data.botplay) + if(FlxG.save.data.botplay && !PlayState.loadRep) ranking = "BotPlay"; if (PlayState.misses == 0 && PlayState.bads == 0 && PlayState.shits == 0 && PlayState.goods == 0) // Marvelous (SICK) Full Combo @@ -86,7 +86,7 @@ class Ratings if (accuracy == 0) ranking = "N/A"; - else if(FlxG.save.data.botplay) + else if(FlxG.save.data.botplay && !PlayState.loadRep) ranking = "BotPlay"; return ranking; @@ -107,35 +107,45 @@ class Ratings // trace('Hit Info\nDifference: ' + noteDiff + '\nZone: ' + Conductor.safeZoneOffset * 1.5 + "\nTS: " + customTimeScale + "\nLate: " + 155 * customTimeScale); - if (FlxG.save.data.botplay) - return "good"; // FUNNY - - if (noteDiff > 166 * customTimeScale) // so god damn early its a miss - return "miss"; - if (noteDiff > 135 * customTimeScale) // way early - return "shit"; - else if (noteDiff > 90 * customTimeScale) // early - return "bad"; - else if (noteDiff > 45 * customTimeScale) // your kinda there - return "good"; - else if (noteDiff < -45 * customTimeScale) // little late - return "good"; - else if (noteDiff < -90 * customTimeScale) // late - return "bad"; - else if (noteDiff < -135 * customTimeScale) // late as fuck - return "shit"; - else if (noteDiff < -166 * customTimeScale) // so god damn late its a miss - return "miss"; - return "sick"; + if (FlxG.save.data.botplay && !PlayState.loadRep) + return "sick"; // FUNNY + + + var rating = checkRating(noteDiff,customTimeScale); + + + return rating; + } + + public static function checkRating(ms:Float, ts:Float) + { + var rating = "sick"; + if (ms <= 166 * ts && ms >= 135 * ts) + rating = "shit"; + if (ms < 135 * ts && ms >= 90 * ts) + rating = "bad"; + if (ms < 90 * ts && ms >= 45 * ts) + rating = "good"; + if (ms < 45 * ts && ms >= -45 * ts) + rating = "sick"; + if (ms > -90 * ts && ms <= -45 * ts) + rating = "good"; + if (ms > -135 * ts && ms <= -90 * ts) + rating = "bad"; + if (ms > -166 * ts && ms <= -135 * ts) + rating = "shit"; + return rating; } public static function CalculateRanking(score:Int,scoreDef:Int,nps:Int,maxNPS:Int,accuracy:Float):String { - return - (FlxG.save.data.npsDisplay ? "NPS: " + nps + " (Max " + maxNPS + ")" + (!FlxG.save.data.botplay ? " | " : "") : "") + (!FlxG.save.data.botplay ? // NPS Toggle - "Score:" + (Conductor.safeFrames != 10 ? score + " (" + scoreDef + ")" : "" + score) + // Score - " | Combo Breaks:" + PlayState.misses + // Misses/Combo Breaks - " | Accuracy:" + (FlxG.save.data.botplay ? "N/A" : HelperFunctions.truncateFloat(accuracy, 2) + " %") + // Accuracy - " | " + GenerateLetterRank(accuracy) : ""); // Letter Rank + return + (FlxG.save.data.npsDisplay ? // NPS Toggle + "NPS: " + nps + " (Max " + maxNPS + ")" + (!PlayStateChangeables.botPlay || PlayState.loadRep ? " | " : "") : "") + // NPS + (!PlayStateChangeables.botPlay || PlayState.loadRep ? "Score:" + (Conductor.safeFrames != 10 ? score + " (" + scoreDef + ")" : "" + score) + // Score + (FlxG.save.data.accuracyDisplay ? // Accuracy Toggle + " | Combo Breaks:" + PlayState.misses + // Misses/Combo Breaks + " | Accuracy:" + (PlayStateChangeables.botPlay && !PlayState.loadRep ? "N/A" : HelperFunctions.truncateFloat(accuracy, 2) + " %") + // Accuracy + " | " + GenerateLetterRank(accuracy) : "") : ""); // Letter Rank } } diff --git a/source/Replay.hx b/source/Replay.hx index bf43d77..18ce656 100644 --- a/source/Replay.hx +++ b/source/Replay.hx @@ -11,81 +11,123 @@ import haxe.Json; import flixel.input.keyboard.FlxKey; import openfl.utils.Dictionary; +class Ana +{ + public var hitTime:Float; + public var nearestNote:Array; + public var hit:Bool; + public var hitJudge:String; + public var key:Int; + public function new(_hitTime:Float,_nearestNote:Array,_hit:Bool,_hitJudge:String, _key:Int) { + hitTime = _hitTime; + nearestNote = _nearestNote; + hit = _hit; + hitJudge = _hitJudge; + key = _key; + } +} + +class Analysis +{ + public var anaArray:Array; + + public function new() { + anaArray = []; + } +} + typedef ReplayJSON = { - public var replayGameVer:String; - public var timestamp:Date; - public var songName:String; - public var songDiff:Int; - public var songNotes:Array; + public var replayGameVer:String; + public var timestamp:Date; + public var songName:String; + public var songDiff:Int; + public var songNotes:Array; + public var songJudgements:Array; public var noteSpeed:Float; public var isDownscroll:Bool; + public var sf:Int; + public var ana:Analysis; } class Replay { - public static var version:String = "1.0"; // replay file version + public static var version:String = "1.2"; // replay file version - public var path:String = ""; - public var replay:ReplayJSON; - public function new(path:String) - { - this.path = path; - replay = { - songName: "Tutorial", - songDiff: 1, + public var path:String = ""; + public var replay:ReplayJSON; + public function new(path:String) + { + this.path = path; + replay = { + songName: "No Song Found", + songDiff: 1, noteSpeed: 1.5, isDownscroll: false, songNotes: [], - replayGameVer: version, - timestamp: Date.now() - }; - } + replayGameVer: version, + timestamp: Date.now(), + sf: Conductor.safeFrames, + ana: new Analysis(), + songJudgements: [] + }; + } - public static function LoadReplay(path:String):Replay + public static function LoadReplay(path:String):Replay { - var rep:Replay = new Replay(path); + var rep:Replay = new Replay(path); - rep.LoadFromJSON(); + rep.LoadFromJSON(); - trace('basic replay data:\nSong Name: ' + rep.replay.songName + '\nSong Diff: ' + rep.replay.songDiff + '\nNotes Length: ' + rep.replay.songNotes.length); + trace('basic replay data:\nSong Name: ' + rep.replay.songName + '\nSong Diff: ' + rep.replay.songDiff); - return rep; - } + return rep; + } - public function SaveReplay(notearray:Array) - { - var json = { - "songName": PlayState.SONG.song.toLowerCase(), - "songDiff": PlayState.storyDifficulty, + public function SaveReplay(notearray:Array, judge:Array, ana:Analysis) + { + var json = { + "songName": PlayState.SONG.song, + "songDiff": PlayState.storyDifficulty, "noteSpeed": (FlxG.save.data.scrollSpeed > 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed), "isDownscroll": FlxG.save.data.downscroll, "songNotes": notearray, - "timestamp": Date.now(), - "replayGameVer": version - }; + "songJudgements": judge, + "timestamp": Date.now(), + "replayGameVer": version, + "sf": Conductor.safeFrames, + "ana": ana + }; - var data:String = Json.stringify(json); + var data:String = Json.stringify(json); + + var time = Date.now().getTime(); - #if sys - File.saveContent("assets/replays/replay-" + PlayState.SONG.song + "-time" + Date.now().getTime() + ".kadeReplay", data); - #end - } + #if sys + File.saveContent("assets/replays/replay-" + PlayState.SONG.song + "-time" + time + ".kadeReplay", data); - public function LoadFromJSON() - { - #if sys - trace('loading ' + Sys.getCwd() + 'assets/replays/' + path + ' replay...'); - try - { - var repl:ReplayJSON = cast Json.parse(File.getContent(Sys.getCwd() + "assets/replays/" + path)); - replay = repl; - } - catch(e) - { - trace('failed!\n' + e.message); - } - #end - } + path = "replay-" + PlayState.SONG.song + "-time" + time + ".kadeReplay"; // for score screen shit + + LoadFromJSON(); + + replay.ana = ana; + #end + } + + public function LoadFromJSON() + { + #if sys + trace('loading ' + Sys.getCwd() + 'assets/replays/' + path + ' replay...'); + try + { + var repl:ReplayJSON = cast Json.parse(File.getContent(Sys.getCwd() + "assets/replays/" + path)); + replay = repl; + } + catch(e) + { + trace('failed!\n' + e.message); + } + #end + } } diff --git a/source/ResultsScreen.hx b/source/ResultsScreen.hx new file mode 100644 index 0000000..108c547 --- /dev/null +++ b/source/ResultsScreen.hx @@ -0,0 +1,252 @@ +package; + +import openfl.geom.Matrix; +import openfl.display.BitmapData; +import flixel.system.FlxSound; +import flixel.util.FlxAxes; +import flixel.FlxSubState; +import Options.Option; +import flixel.input.FlxInput; +import flixel.input.keyboard.FlxKey; +import flixel.FlxG; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.effects.FlxFlicker; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; +import io.newgrounds.NG; +import lime.app.Application; +import lime.utils.Assets; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.input.FlxKeyManager; + + +using StringTools; + +class ResultsScreen extends FlxSubState +{ + public var background:FlxSprite; + public var text:FlxText; + + public var anotherBackground:FlxSprite; + public var graph:HitGraph; + public var graphSprite:OFLSprite; + + public var comboText:FlxText; + public var contText:FlxText; + public var settingsText:FlxText; + + public var music:FlxSound; + + public var graphData:BitmapData; + + public var ranking:String; + public var accuracy:String; + + override function create() + { + background = new FlxSprite(0,0).makeGraphic(FlxG.width,FlxG.height,FlxColor.BLACK); + background.scrollFactor.set(); + add(background); + + music = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true); + music.volume = 0; + music.play(false, FlxG.random.int(0, Std.int(music.length / 2))); + + background.alpha = 0; + + text = new FlxText(20,-55,0,"Song Cleared!"); + text.size = 34; + text.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1); + text.color = FlxColor.WHITE; + text.scrollFactor.set(); + add(text); + + var score = PlayState.instance.songScore; + if (PlayState.isStoryMode) + { + score = PlayState.campaignScore; + text.text = "Week Cleared!"; + } + + comboText = new FlxText(20,-75,0,'Judgements:\nSicks - ${PlayState.sicks}\nGoods - ${PlayState.goods}\nBads - ${PlayState.bads}\n\nCombo Breaks: ${(PlayState.isStoryMode ? PlayState.campaignMisses : PlayState.misses)}\nHighest Combo: ${PlayState.highestCombo + 1}\n\nScore: ${PlayState.instance.songScore}\nAccuracy: ${HelperFunctions.truncateFloat(PlayState.instance.accuracy,2)}%\n\n${Ratings.GenerateLetterRank(PlayState.instance.accuracy)}\n\nF1 - View replay\nF2 - Replay song + '); + comboText.size = 28; + comboText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1); + comboText.color = FlxColor.WHITE; + comboText.scrollFactor.set(); + add(comboText); + + contText = new FlxText(FlxG.width - 475,FlxG.height + 50,0,'Press ENTER to continue.'); + contText.size = 28; + contText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1); + contText.color = FlxColor.WHITE; + contText.scrollFactor.set(); + add(contText); + + anotherBackground = new FlxSprite(FlxG.width - 500,45).makeGraphic(450,240,FlxColor.BLACK); + anotherBackground.scrollFactor.set(); + anotherBackground.alpha = 0; + add(anotherBackground); + + graph = new HitGraph(FlxG.width - 500,45,495,240); + graph.alpha = 0; + + graphSprite = new OFLSprite(FlxG.width - 510,45,460,240,graph); + + graphSprite.scrollFactor.set(); + graphSprite.alpha = 0; + + add(graphSprite); + + + var sicks = HelperFunctions.truncateFloat(PlayState.sicks / PlayState.goods,1); + var goods = HelperFunctions.truncateFloat(PlayState.goods / PlayState.bads,1); + + if (sicks == Math.POSITIVE_INFINITY) + sicks = 0; + if (goods == Math.POSITIVE_INFINITY) + goods = 0; + + var mean:Float = 0; + + + for (i in 0...PlayState.rep.replay.songNotes.length) + { + // 0 = time + // 1 = length + // 2 = type + // 3 = diff + var obj = PlayState.rep.replay.songNotes[i]; + // judgement + var obj2 = PlayState.rep.replay.songJudgements[i]; + + var obj3 = obj[0]; + + var diff = obj[3]; + var judge = obj2; + mean += diff; + if (obj[1] != -1) + graph.addToHistory(diff, judge, obj3); + } + + graph.update(); + + mean = HelperFunctions.truncateFloat(mean / PlayState.rep.replay.songNotes.length,2); + + settingsText = new FlxText(20,FlxG.height + 50,0,'SF: ${PlayState.rep.replay.sf} | Ratio (SA/GA): ${Math.round(sicks)}:1 ${Math.round(goods)}:1 | Mean: ${mean}ms | Played on ${PlayState.SONG.song} ${CoolUtil.difficultyFromInt(PlayState.storyDifficulty).toUpperCase()}'); + settingsText.size = 16; + settingsText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,2,1); + settingsText.color = FlxColor.WHITE; + settingsText.scrollFactor.set(); + add(settingsText); + + + FlxTween.tween(background, {alpha: 0.5},0.5); + FlxTween.tween(text, {y:20},0.5,{ease: FlxEase.expoInOut}); + FlxTween.tween(comboText, {y:145},0.5,{ease: FlxEase.expoInOut}); + FlxTween.tween(contText, {y:FlxG.height - 45},0.5,{ease: FlxEase.expoInOut}); + FlxTween.tween(settingsText, {y:FlxG.height - 35},0.5,{ease: FlxEase.expoInOut}); + FlxTween.tween(anotherBackground, {alpha: 0.6},0.5, {onUpdate: function(tween:FlxTween) { + graph.alpha = FlxMath.lerp(0,1,tween.percent); + graphSprite.alpha = FlxMath.lerp(0,1,tween.percent); + }}); + + cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; + + super.create(); + } + + + var frames = 0; + + override function update(elapsed:Float) + { + if (music.volume < 0.5) + music.volume += 0.01 * elapsed; + + // keybinds + + if (FlxG.keys.justPressed.ENTER) + { + music.fadeOut(0.3); + + PlayState.loadRep = false; + PlayState.rep = null; + + if (PlayState.isStoryMode) + { + FlxG.sound.playMusic(Paths.music('freakyMenu')); + FlxG.switchState(new MainMenuState()); + } + else + FlxG.switchState(new FreeplayState()); + } + + if (FlxG.keys.justPressed.EIGHT) + { + graph.showInput = !graph.showInput; + graph.update(); + } + + if (FlxG.keys.justPressed.F1) + { + trace(PlayState.rep.path); + PlayState.rep = Replay.LoadReplay(PlayState.rep.path); + + PlayState.loadRep = true; + + var songFormat = StringTools.replace(PlayState.rep.replay.songName, " ", "-"); + switch (songFormat) { + case 'Dad-Battle': songFormat = 'Dadbattle'; + case 'Philly-Nice': songFormat = 'Philly'; + // Replay v1.0 support + case 'dad-battle': songFormat = 'Dadbattle'; + case 'philly-nice': songFormat = 'Philly'; + } + + var poop:String = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff); + + music.fadeOut(0.3); + + PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName); + PlayState.isStoryMode = false; + PlayState.storyDifficulty = PlayState.rep.replay.songDiff; + PlayState.storyWeek = 0; + LoadingState.loadAndSwitchState(new PlayState()); + } + + if (FlxG.keys.justPressed.F2 ) + { + PlayState.rep = null; + + PlayState.loadRep = false; + + var songFormat = StringTools.replace(PlayState.SONG.song, " ", "-"); + switch (songFormat) { + case 'Dad-Battle': songFormat = 'Dadbattle'; + case 'Philly-Nice': songFormat = 'Philly'; + case 'dad-battle': songFormat = 'Dadbattle'; + case 'philly-nice': songFormat = 'Philly'; + } + + var poop:String = Highscore.formatSong(songFormat, PlayState.storyDifficulty); + + music.fadeOut(0.3); + + PlayState.SONG = Song.loadFromJson(poop, PlayState.SONG.song); + PlayState.isStoryMode = false; + PlayState.storyDifficulty = PlayState.storyDifficulty; + PlayState.storyWeek = 0; + LoadingState.loadAndSwitchState(new PlayState()); + } + + super.update(elapsed); + + } +} diff --git a/source/Song.hx b/source/Song.hx index d7bf608..5329079 100644 --- a/source/Song.hx +++ b/source/Song.hx @@ -33,9 +33,9 @@ class Song public var player1:String = 'bf'; public var player2:String = 'dad'; - public var gfVersion:String = 'gf'; - public var noteStyle:String = 'normal'; - public var stage:String = 'stage'; + public var gfVersion:String = ''; + public var noteStyle:String = ''; + public var stage:String = ''; public function new(song, notes, bpm) { @@ -46,9 +46,18 @@ class Song public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong { - trace('loading ' + folder.toLowerCase() + '/' + jsonInput.toLowerCase()); + trace(jsonInput); - var rawJson = Assets.getText(Paths.json(folder.toLowerCase() + '/' + jsonInput.toLowerCase())).trim(); + // pre lowercasing the folder name + var folderLowercase = StringTools.replace(folder, " ", "-").toLowerCase(); + switch (folderLowercase) { + case 'dad-battle': folderLowercase = 'dadbattle'; + case 'philly-nice': folderLowercase = 'philly'; + } + + trace('loading ' + folderLowercase + '/' + jsonInput.toLowerCase()); + + var rawJson = Assets.getText(Paths.json(folderLowercase + '/' + jsonInput.toLowerCase())).trim(); while (!rawJson.endsWith("}")) { diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx index 501cf2b..443b8e0 100644 --- a/source/StoryMenuState.hx +++ b/source/StoryMenuState.hx @@ -285,19 +285,23 @@ class StoryMenuState extends MusicBeatState PlayState.isStoryMode = true; selectedWeek = true; - var diffic = ""; - - switch (curDifficulty) - { - case 0: - diffic = '-easy'; - case 2: - diffic = '-hard'; - } PlayState.storyDifficulty = curDifficulty; - PlayState.SONG = Song.loadFromJson(StringTools.replace(PlayState.storyPlaylist[0]," ", "-").toLowerCase() + diffic, StringTools.replace(PlayState.storyPlaylist[0]," ", "-").toLowerCase()); + // adjusting the song name to be compatible + var songFormat = StringTools.replace(PlayState.storyPlaylist[0], " ", "-"); + switch (songFormat) { + case 'Dad-Battle': songFormat = 'Dadbattle'; + case 'Philly-Nice': songFormat = 'Philly'; + } + + var poop:String = Highscore.formatSong(songFormat, curDifficulty); + PlayState.sicks = 0; + PlayState.bads = 0; + PlayState.shits = 0; + PlayState.goods = 0; + PlayState.campaignMisses = 0; + PlayState.SONG = Song.loadFromJson(poop, PlayState.storyPlaylist[0]); PlayState.storyWeek = curWeek; PlayState.campaignScore = 0; new FlxTimer().start(1, function(tmr:FlxTimer) diff --git a/source/TitleState.hx b/source/TitleState.hx index 8b5a281..6b86eca 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -163,14 +163,25 @@ class TitleState extends MusicBeatState // bg.updateHitbox(); add(bg); - logoBl = new FlxSprite(-150, -100); - logoBl.frames = Paths.getSparrowAtlas('logoBumpin'); - logoBl.antialiasing = true; - logoBl.animation.addByPrefix('bump', 'logo bumpin', 24); - logoBl.animation.play('bump'); - logoBl.updateHitbox(); - // logoBl.screenCenter(); - // logoBl.color = FlxColor.BLACK; + if(Main.watermarks) { + logoBl = new FlxSprite(-150, -100); + logoBl.frames = Paths.getSparrowAtlas('KadeEngineLogoBumpin'); + logoBl.antialiasing = true; + logoBl.animation.addByPrefix('bump', 'logo bumpin', 24); + logoBl.animation.play('bump'); + logoBl.updateHitbox(); + // logoBl.screenCenter(); + // logoBl.color = FlxColor.BLACK; + } else { + logoBl = new FlxSprite(-150, -100); + logoBl.frames = Paths.getSparrowAtlas('logoBumpin'); + logoBl.antialiasing = true; + logoBl.animation.addByPrefix('bump', 'logo bumpin', 24); + logoBl.animation.play('bump'); + logoBl.updateHitbox(); + // logoBl.screenCenter(); + // logoBl.color = FlxColor.BLACK; + } gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.07); gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle'); diff --git a/source/VideoHandler.hx b/source/VideoHandler.hx new file mode 100644 index 0000000..1b01699 --- /dev/null +++ b/source/VideoHandler.hx @@ -0,0 +1,195 @@ +//This was made by GWebDev lol btw this uses actuate +package; + +import motion.Actuate; +import openfl.display.Sprite; +import openfl.events.AsyncErrorEvent; +import openfl.events.MouseEvent; +import openfl.events.NetStatusEvent; +import openfl.media.Video; +import openfl.net.NetConnection; +import openfl.net.NetStream; +import flixel.FlxG; + +using StringTools; + +class VideoHandler +{ + public var netStream:NetStream; + public var video:Video; + public var isReady:Bool = false; + public var addOverlay:Bool = false; + public var vidPath:String = ""; + public var ignoreShit:Bool = false; + + public function new() + { + isReady = false; + } + + public function source(?vPath:String):Void + { + if (vPath != null && vPath.length > 0) + { + vidPath = vPath; + } + } + + public function init1():Void + { + isReady = false; + video = new Video(); + video.visible = false; + } + + public function init2():Void + { + #if web + var netConnection = new NetConnection (); + netConnection.connect (null); + + netStream = new NetStream (netConnection); + netStream.client = { onMetaData: client_onMetaData }; + netStream.addEventListener (AsyncErrorEvent.ASYNC_ERROR, netStream_onAsyncError); + + netConnection.addEventListener (NetStatusEvent.NET_STATUS, netConnection_onNetStatus); + netConnection.addEventListener (NetStatusEvent.NET_STATUS, onPlay); + netConnection.addEventListener (NetStatusEvent.NET_STATUS, onEnd); + #end + } + + public function client_onMetaData (metaData:Dynamic) { + + video.attachNetStream (netStream); + + video.width = FlxG.width; + video.height = FlxG.height; + + } + + + public function netStream_onAsyncError (event:AsyncErrorEvent):Void { + + trace ("Error loading video"); + + } + + + public function netConnection_onNetStatus (event:NetStatusEvent):Void { + trace (event.info.code); + } + + public function play():Void + { + #if web + ignoreShit = true; + netStream.close(); + init2(); + netStream.play(vidPath); + ignoreShit = false; + #end + trace(vidPath); + } + + public function stop():Void + { + netStream.close(); + onStop(); + } + + public function restart():Void + { + play(); + onRestart(); + } + + public function update(elapsed:Float):Void + { + video.x = GlobalVideo.calc(0); + video.y = GlobalVideo.calc(1); + video.width = GlobalVideo.calc(2); + video.height = GlobalVideo.calc(3); + } + + public var stopped:Bool = false; + public var restarted:Bool = false; + public var played:Bool = false; + public var ended:Bool = false; + public var paused:Bool = false; + + public function pause():Void + { + netStream.pause(); + paused = true; + } + + public function resume():Void + { + netStream.resume(); + paused = false; + } + + public function togglePause():Void + { + if (paused) + { + resume(); + } else { + pause(); + } + } + + public function clearPause():Void + { + paused = false; + } + + public function onStop():Void + { + if (!ignoreShit) + { + stopped = true; + } + } + + public function onRestart():Void + { + restarted = true; + } + + public function onPlay(event:NetStatusEvent):Void + { + if (event.info.code == "NetStream.Play.Start") + { + played = true; + } + } + + public function onEnd(event:NetStatusEvent):Void + { + if (event.info.code == "NetStream.Play.Complete") + { + ended = true; + } + } + + public function alpha():Void + { + video.alpha = GlobalVideo.daAlpha1; + } + + public function unalpha():Void + { + video.alpha = GlobalVideo.daAlpha2; + } + + public function hide():Void + { + video.visible = false; + } + + public function show():Void + { + video.visible = true; + } +} \ No newline at end of file diff --git a/source/WebmHandler.hx b/source/WebmHandler.hx new file mode 100644 index 0000000..77b9391 --- /dev/null +++ b/source/WebmHandler.hx @@ -0,0 +1,169 @@ +package; + +import flixel.FlxG; +import openfl.display.Sprite; +#if desktop +import webm.*; +#end + +class WebmHandler +{ + #if desktop + public var webm:WebmPlayer; + public var vidPath:String = ""; + public var io:WebmIo; + public var initialized:Bool = false; + + public function new() + { + } + + public function source(?vPath:String):Void + { + if (vPath != null && vPath.length > 0) + { + vidPath = vPath; + } + } + + public function makePlayer():Void + { + io = new WebmIoFile(vidPath); + webm = new WebmPlayer(); + webm.fuck(io, false); + webm.addEventListener(WebmEvent.PLAY, function(e) { + onPlay(); + }); + webm.addEventListener(WebmEvent.COMPLETE, function(e) { + onEnd(); + }); + webm.addEventListener(WebmEvent.STOP, function(e) { + onStop(); + }); + webm.addEventListener(WebmEvent.RESTART, function(e) { + onRestart(); + }); + webm.visible = false; + initialized = true; + } + + public function updatePlayer():Void + { + io = new WebmIoFile(vidPath); + webm.fuck(io, false); + } + + public function play():Void + { + if (initialized) + { + webm.play(); + } + } + + public function stop():Void + { + if (initialized) + { + webm.stop(); + } + } + + public function restart():Void + { + if (initialized) + { + webm.restart(); + } + } + + public function update(elapsed:Float) + { + webm.x = GlobalVideo.calc(0); + webm.y = GlobalVideo.calc(1); + webm.width = GlobalVideo.calc(2); + webm.height = GlobalVideo.calc(3); + } + + public var stopped:Bool = false; + public var restarted:Bool = false; + public var played:Bool = false; + public var ended:Bool = false; + public var paused:Bool = false; + + public function pause():Void + { + webm.changePlaying(false); + paused = true; + } + + public function resume():Void + { + webm.changePlaying(true); + paused = false; + } + + public function togglePause():Void + { + if (paused) + { + resume(); + } else { + pause(); + } + } + + public function clearPause():Void + { + paused = false; + webm.removePause(); + } + + public function onStop():Void + { + stopped = true; + } + + public function onRestart():Void + { + restarted = true; + } + + public function onPlay():Void + { + played = true; + } + + public function onEnd():Void + { + trace("IT ENDED!"); + ended = true; + } + + public function alpha():Void + { + webm.alpha = GlobalVideo.daAlpha1; + } + + public function unalpha():Void + { + webm.alpha = GlobalVideo.daAlpha2; + } + + public function hide():Void + { + webm.visible = false; + } + + public function show():Void + { + webm.visible = true; + } + #else + public var webm:Sprite; + public function new() + { + trace("THIS IS ANDROID! or some shit..."); + } + #end +} \ No newline at end of file