diff --git a/assets/images/UI/simplylove/base/combo.png b/assets/images/UI/simplylove/base/combo.png new file mode 100644 index 000000000..d65ee404c Binary files /dev/null and b/assets/images/UI/simplylove/base/combo.png differ diff --git a/assets/images/dialogue/boxes/dialogueBox-evil/dialogueBox-evil.json b/assets/images/dialogue/boxes/dialogueBox-evil/dialogueBox-evil.json new file mode 100644 index 000000000..e36407bce --- /dev/null +++ b/assets/images/dialogue/boxes/dialogueBox-evil/dialogueBox-evil.json @@ -0,0 +1,15 @@ +{ + "position": [515, 370], + "textPos": [200, 480], + "scale": 5.4, + "antialiasing": false, + "singleFrame": true, + "doFlip": false, + "bgColor": [255, 255, 255], + "states": { + "normal": { + "open": ["Spirit Textbox spawn instance 1"], + "default": ["Spirit Textbox spawn instance 1"] + } + } +} \ No newline at end of file diff --git a/assets/images/dialogue/boxes/dialogueBox-evil/dialogueBox-evil.png b/assets/images/dialogue/boxes/dialogueBox-evil/dialogueBox-evil.png new file mode 100644 index 000000000..5f0a44588 Binary files /dev/null and b/assets/images/dialogue/boxes/dialogueBox-evil/dialogueBox-evil.png differ diff --git a/assets/images/dialogue/boxes/dialogueBox-evil/dialogueBox-evil.xml b/assets/images/dialogue/boxes/dialogueBox-evil/dialogueBox-evil.xml new file mode 100644 index 000000000..94a1fb456 --- /dev/null +++ b/assets/images/dialogue/boxes/dialogueBox-evil/dialogueBox-evil.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/images/menus/base/title/FELogo.png b/assets/images/menus/base/title/FELogo.png deleted file mode 100644 index c6f31ca4f..000000000 Binary files a/assets/images/menus/base/title/FELogo.png and /dev/null differ diff --git a/assets/images/menus/base/title/foreverlogo.png b/assets/images/menus/base/title/foreverlogo.png new file mode 100644 index 000000000..5cb1fd972 Binary files /dev/null and b/assets/images/menus/base/title/foreverlogo.png differ diff --git a/assets/images/menus/base/title/foreverlogo.xml b/assets/images/menus/base/title/foreverlogo.xml new file mode 100644 index 000000000..0a4dc3542 --- /dev/null +++ b/assets/images/menus/base/title/foreverlogo.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/songs/roses/dialogue.json b/assets/songs/roses/dialogue.json new file mode 100644 index 000000000..20e212d4d --- /dev/null +++ b/assets/songs/roses/dialogue.json @@ -0,0 +1,18 @@ +{ + "box": "dialogueBox-pixel", + "boxState": "normal", + "dialogue": [ + { + "portrait": "senpai", + "expression": "mad", + "text": "Not bad for an ugly worm." + }, + { + "text": "But this time I'll rip your nuts off \nright after your girlfriend \nfinishes gargling mine." + }, + { + "portrait": "bf-pixel", + "text": "Bop beep be be skdoo bep" + } + ] +} \ No newline at end of file diff --git a/assets/songs/roses/rosesDialogue.txt b/assets/songs/roses/rosesDialogue.txt deleted file mode 100644 index 63a60f81b..000000000 --- a/assets/songs/roses/rosesDialogue.txt +++ /dev/null @@ -1,3 +0,0 @@ -:dad:Not bad for an ugly worm. -:dad:But this time I'll rip your nuts off right after your girlfriend finishes gargling mine. -:bf:Bop beep be be skdoo bep \ No newline at end of file diff --git a/assets/songs/senpai/dialogue.json b/assets/songs/senpai/dialogue.json index 1f370dddc..4173cc7ae 100644 --- a/assets/songs/senpai/dialogue.json +++ b/assets/songs/senpai/dialogue.json @@ -5,10 +5,10 @@ { "portrait": "senpai", "expression": "normal", - "text": "Ah, a new fair maiden has come in search of true love!" + "text": "Ah, a new fair maiden has come \nin search of true love!" }, { - "text": "A serenade between gentlemen shall decide where her beautiful heart shall reside." + "text": "A serenade between gentlemen \nshall decide where her beautiful \nheart shall reside." }, { "portrait": "bf-pixel", diff --git a/assets/songs/senpai/senpaiDialogue.txt b/assets/songs/senpai/senpaiDialogue.txt deleted file mode 100644 index af03e3798..000000000 --- a/assets/songs/senpai/senpaiDialogue.txt +++ /dev/null @@ -1,3 +0,0 @@ -:dad:Ah, a new fair maiden has come in search of true love! -:dad:A serenade between gentlemen shall decide where her beautiful heart shall reside. -:bf:Beep bo bop \ No newline at end of file diff --git a/assets/songs/thorns/dialogue.json b/assets/songs/thorns/dialogue.json new file mode 100644 index 000000000..42a27c38f --- /dev/null +++ b/assets/songs/thorns/dialogue.json @@ -0,0 +1,23 @@ +{ + "box": "dialogueBox-evil", + "boxState": "normal", + "dialogue": [ + { + "portrait": "senpai", + "expression": "mad", + "text": "Direct contact with real humans, \nafter being trapped in here for \nso long..." + }, + { + "text": "and HER of all people." + }, + { + "text": "I'll make her father pay for what \nhe's done to me and all the \nothers,,,," + }, + { + "text": "I'll beat you and make you take \nmy place." + }, + { + "text": "You don't mind your bodies \nbeing borrowed right? It's only \nfair..." + } + ] +} \ No newline at end of file diff --git a/assets/songs/thorns/thornsDialogue.txt b/assets/songs/thorns/thornsDialogue.txt deleted file mode 100644 index b4302027b..000000000 --- a/assets/songs/thorns/thornsDialogue.txt +++ /dev/null @@ -1,5 +0,0 @@ -:dad:Direct contact with real humans, after being trapped in here for so long... -:dad:and HER of all people. -:dad:I'll make her father pay for what he's done to me and all the others,,,, -:dad:I'll beat you and make you take my place. -:dad:You don't mind your bodies being borrowed right? It's only fair... \ No newline at end of file diff --git a/source/ForeverAssets.hx b/source/ForeverAssets.hx index 90b371c17..1e6365e13 100644 --- a/source/ForeverAssets.hx +++ b/source/ForeverAssets.hx @@ -185,9 +185,9 @@ class ForeverAssets newStaticArrow.updateHitbox(); newStaticArrow.antialiasing = false; - newStaticArrow.addOffset('static', -67, -75); - newStaticArrow.addOffset('pressed', -67, -75); - newStaticArrow.addOffset('confirm', -67, -75); + newStaticArrow.addOffset('static', -67, -50); + newStaticArrow.addOffset('pressed', -67, -50); + newStaticArrow.addOffset('confirm', -67, -50); case 'chart editor': newStaticArrow.loadGraphic(Paths.image('UI/forever/base/chart editor/note_array'), true, 157, 156); diff --git a/source/Init.hx b/source/Init.hx index c7bcc43e1..bb92a949b 100644 --- a/source/Init.hx +++ b/source/Init.hx @@ -13,6 +13,15 @@ import openfl.filters.ColorMatrixFilter; using StringTools; +/** + Enumerator for settingtypes +**/ +enum SettingTypes +{ + Checkmark; + Selector; +} + /** This is the initialisation class. if you ever want to set anything before the game starts or call anything then this is probably your best bet. A lot of this code is just going to be similar to the flixel templates' colorblind filters because I wanted to add support for those as I'll @@ -36,93 +45,94 @@ class Init extends FlxState public static var gameSettings:Map = [ 'Downscroll' => [ false, - 0, + Checkmark, 'Whether to have the strumline vertically flipped in gameplay.', NOT_FORCED ], - 'Auto Pause' => [true, 0, '', NOT_FORCED], - 'FPS Counter' => [true, 0, 'Whether to display the FPS counter.', NOT_FORCED], + 'Auto Pause' => [true, Checkmark, '', NOT_FORCED], + 'FPS Counter' => [true, Checkmark, 'Whether to display the FPS counter.', NOT_FORCED], 'Memory Counter' => [ true, - 0, + Checkmark, 'Whether to display approximately how much memory is being used.', NOT_FORCED ], - 'Debug Info' => [false, 0, 'Whether to display information like your game state.', NOT_FORCED], + 'Debug Info' => [false, Checkmark, 'Whether to display information like your game state.', NOT_FORCED], 'Reduced Movements' => [ false, - 0, + Checkmark, 'Whether to reduce movements, like icons bouncing or beat zooms in gameplay.', NOT_FORCED ], 'Stage Darkness' => [ - 0, - 1, + Checkmark, + Selector, 'Darkens non-ui elements, useful if you find the characters and backgrounds distracting.', NOT_FORCED ], - 'Display Accuracy' => [true, 0, 'Whether to display your accuracy on screen.', NOT_FORCED], + 'Display Accuracy' => [true, Checkmark, 'Whether to display your accuracy on screen.', NOT_FORCED], 'Disable Antialiasing' => [ false, - 0, + Checkmark, 'Whether to disable Anti-aliasing. Helps improve performance in FPS.', NOT_FORCED ], 'No Camera Note Movement' => [ false, - 0, + Checkmark, 'When enabled, left and right notes no longer move the camera.', NOT_FORCED ], 'Use Forever Chart Editor' => [ true, - 0, + Checkmark, 'When enabled, uses the custom Forever Engine chart editor!', NOT_FORCED ], 'Disable Note Splashes' => [ false, - 0, + Checkmark, 'Whether to disable note splashes in gameplay. Useful if you find them distracting.', NOT_FORCED ], // custom ones lol - 'Offset' => [0, 3], + 'Offset' => [Checkmark, 3], 'Filter' => [ 'none', - 1, + Selector, 'Choose a filter for colorblindness.', NOT_FORCED, ['none', 'Deuteranopia', 'Protanopia', 'Tritanopia'] ], - "UI Skin" => ['default', 1, 'Choose a UI Skin for judgements, combo, etc.', NOT_FORCED, ''], - "Note Skin" => ['default', 1, 'Choose a note skin.', NOT_FORCED, ''], - "Framerate Cap" => [120, 1, 'Define your maximum FPS.', NOT_FORCED, ['']], - "Opaque Arrows" => [false, 0, "Makes the arrows at the top of the screen opaque again.", NOT_FORCED], - "Opaque Holds" => [false, 0, "Huh, why isnt the trail cut off?", NOT_FORCED], + "UI Skin" => ['default', Selector, 'Choose a UI Skin for judgements, combo, etc.', NOT_FORCED, ''], + "Note Skin" => ['default', Selector, 'Choose a note skin.', NOT_FORCED, ''], + "Framerate Cap" => [120, Selector, 'Define your maximum FPS.', NOT_FORCED, ['']], + "Opaque Arrows" => [false, Checkmark, "Makes the arrows at the top of the screen opaque again.", NOT_FORCED], + "Opaque Holds" => [false, Checkmark, "Huh, why isnt the trail cut off?", NOT_FORCED], 'Ghost Tapping' => [ false, - 0, + Checkmark, "Enables Ghost Tapping, allowing you to press inputs without missing.", NOT_FORCED ], - 'Centered Notefield' => [false, 0, "Center the notes, disables the enemy's notes."], + 'Centered Notefield' => [false, Checkmark, "Center the notes, disables the enemy's notes."], "Custom Titlescreen" => [ false, - 0, + Checkmark, "Enables the custom Forever Engine titlescreen! (only effective with a restart)", FORCED ], - 'Skip Cutscenes' => [false, 0, 'Skip the cutscenes in story mode. (Includes Dialogue)'], - 'SM-like Judgements' => [ - false, - 0, - "Fixes the judgements to the camera instead of to the world itself, making them easier to read." + 'Skip Text' => [ + 'never', + Selector, + 'Decides whether to skip cutscenes and dialogue in gameplay. May be always, only in freeplay, or never.', + NOT_FORCED, + ['never', 'freeplay only', 'always'] ], - 'Display Miss Count' => [ + 'Fixed Judgements' => [ false, - 0, - "When enabled, displays the amount of combo breaks you have in a song." + Checkmark, + "Fixes the judgements to the camera instead of to the world itself, making them easier to read." ], ]; @@ -188,8 +198,7 @@ class Init extends FlxState // apply saved filters FlxG.game.setFilters(filters); - // Some additional changes to default HaxeFlixel settings, both for ease of debugging - // and usability. + // Some additional changes to default HaxeFlixel settings, both for ease of debugging and usability. FlxG.fixedTimestep = false; // This ensures that the game is not tied to the FPS FlxG.mouse.useSystemCursor = true; // Use system cursor because it's prettier FlxG.mouse.visible = false; // Hide mouse on start diff --git a/source/gameFolder/gameObjects/Stage.hx b/source/gameFolder/gameObjects/Stage.hx index 3f872f695..c12765d9b 100644 --- a/source/gameFolder/gameObjects/Stage.hx +++ b/source/gameFolder/gameObjects/Stage.hx @@ -49,10 +49,11 @@ class Stage extends FlxTypedGroup var daPixelZoom = PlayState.daPixelZoom; + public var foreground:FlxTypedGroup; + public function new(curStage) { super(); - this.curStage = curStage; /// get hardcoded stage type if chart is fnf style @@ -83,6 +84,9 @@ class Stage extends FlxTypedGroup PlayState.curStage = curStage; } + // to apply to foreground use foreground.add(); instead of add(); + foreground = new FlxTypedGroup(); + // switch (curStage) { diff --git a/source/gameFolder/gameObjects/userInterface/ClassHUD.hx b/source/gameFolder/gameObjects/userInterface/ClassHUD.hx index 1bca27a79..9df96ab12 100644 --- a/source/gameFolder/gameObjects/userInterface/ClassHUD.hx +++ b/source/gameFolder/gameObjects/userInterface/ClassHUD.hx @@ -74,7 +74,7 @@ class ClassHUD extends FlxTypedGroup iconP2.y = healthBar.y - (iconP2.height / 2); add(iconP2); - scoreBar = new FlxText(FlxG.width / 2, healthBarBG.y + 50, 0, scoreDisplay, 20); + scoreBar = new FlxText(FlxG.width / 2, healthBarBG.y + 40, 0, scoreDisplay, 20); scoreBar.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); updateScoreText(); scoreBar.scrollFactor.set(); @@ -136,8 +136,7 @@ class ClassHUD extends FlxTypedGroup if (displayAccuracy) { scoreBar.text += ' // Accuracy: ' + Std.string(Math.floor(Timings.getAccuracy() * 100) / 100) + '%' + Timings.comboDisplay; - if (Init.trueSettings.get('Display Miss Count')) - scoreBar.text += ' // Combo Breaks: ' + Std.string(PlayState.misses); + scoreBar.text += ' // Combo Breaks: ' + Std.string(PlayState.misses); scoreBar.text += ' // Rank: ' + Std.string(Timings.returnScoreRating().toUpperCase()); } diff --git a/source/gameFolder/gameObjects/userInterface/DialogueBox.hx b/source/gameFolder/gameObjects/userInterface/DialogueBox.hx index 009c0d3fa..97adc885d 100644 --- a/source/gameFolder/gameObjects/userInterface/DialogueBox.hx +++ b/source/gameFolder/gameObjects/userInterface/DialogueBox.hx @@ -69,26 +69,26 @@ class DialogueBox extends FlxSpriteGroup nothing yet :P */ - var box:FNFSprite; - var bgFade:FlxSprite; - var portrait:FNFSprite; - var text:FlxText; - var alphabetText:Alphabet; + public var box:FNFSprite; + public var bgFade:FlxSprite; + public var portrait:FNFSprite; + public var text:FlxText; + public var alphabetText:Alphabet; - var dialogueData:DialogueFileDataDef; - var portraitData:PortraitDataDef; - var boxData:BoxDataDef; + public var dialogueData:DialogueFileDataDef; + public var portraitData:PortraitDataDef; + public var boxData:BoxDataDef; - var curPage:Int = 0; - var curCharacter:String; - var curExpression:String; - var curBoxState:String; + public var curPage:Int = 0; + public var curCharacter:String; + public var curExpression:String; + public var curBoxState:String; - var eventImage:Null; + public var eventImage:Null; public var whenDaFinish:Void->Void; - var textStarted:Bool = false; + public var textStarted:Bool = false; public static function createDialogue(thisDialogue:String):DialogueBox { @@ -97,7 +97,7 @@ class DialogueBox extends FlxSpriteGroup return newDialogue; } - function dialoguePath(file:String):String + public function dialoguePath(file:String):String { var dialoguePath = Paths.file('assets/images/dialogue/portraits/$curCharacter/$file'); var truePath = Paths.file(file); @@ -162,7 +162,7 @@ class DialogueBox extends FlxSpriteGroup add(skipText); } - function updateDialog(force:Bool = false) + public function updateDialog(force:Bool = false) { // set current portrait updateTextBox(force); @@ -211,7 +211,7 @@ class DialogueBox extends FlxSpriteGroup startText(); } - function updateTextBox(force:Bool = false) + public function updateTextBox(force:Bool = false) { var curBox = dialogueData.box; var newState = dialogueData.dialogue[curPage].boxState; @@ -303,7 +303,7 @@ class DialogueBox extends FlxSpriteGroup } } - function updatePortrait(force:Bool = false) + public function updatePortrait(force:Bool = false) { var newChar = dialogueData.dialogue[curPage].portrait; @@ -487,14 +487,15 @@ class DialogueBox extends FlxSpriteGroup } // mario - function closeDialog() + // WOAH THE CODIST I LOVE MARIO!!! + public function closeDialog() { whenDaFinish(); alphabetText.playSounds = false; kill(); } - function dialogDataCheck() + public function dialogDataCheck() { var tisOkay = true; @@ -525,21 +526,6 @@ class DialogueBox extends FlxSpriteGroup if (bgFade.alpha > 0.6) bgFade.alpha = 0.6; - if (FlxG.keys.justPressed.SHIFT) - closeDialog(); - - if (FlxG.keys.justPressed.ANY && textStarted) - { - FlxG.sound.play(Paths.sound('cancelMenu')); - - curPage += 1; - - if (curPage == dialogueData.dialogue.length) - closeDialog() - else - updateDialog(); - } - super.update(elapsed); } } diff --git a/source/gameFolder/gameObjects/userInterface/notes/Strumline.hx b/source/gameFolder/gameObjects/userInterface/notes/Strumline.hx index a718d10ec..ebc7dd83d 100644 --- a/source/gameFolder/gameObjects/userInterface/notes/Strumline.hx +++ b/source/gameFolder/gameObjects/userInterface/notes/Strumline.hx @@ -79,9 +79,7 @@ class UIStaticArrow extends FlxSprite } public function addOffset(name:String, x:Float = 0, y:Float = 0) - { animOffsets[name] = [x, y]; - } public static function getArrowFromNumber(numb:Int) { diff --git a/source/gameFolder/meta/data/Timings.hx b/source/gameFolder/meta/data/Timings.hx index b08dd5741..bb17f66cb 100644 --- a/source/gameFolder/meta/data/Timings.hx +++ b/source/gameFolder/meta/data/Timings.hx @@ -16,11 +16,11 @@ class Timings // from left to right // max milliseconds, score from it and percentage public static var judgementsMap:Map> = [ - "sick" => [0, 45, 350, 100], - "good" => [1, 100, 150, 40], - "bad" => [2, 120, 0, 5], - "shit" => [3, 140, -50, -100], - "miss" => [4, 180, -100, -150], + "sick" => [0, 50, 350, 100], + "good" => [1, 100, 150, 75], + "bad" => [2, 120, 0, 25], + "shit" => [3, 160, -50, -150], + "miss" => [4, 200, -100, -175], ]; public static var msThreshold:Float = 0; diff --git a/source/gameFolder/meta/data/font/Alphabet.hx b/source/gameFolder/meta/data/font/Alphabet.hx index d81d5964a..178a065d0 100644 --- a/source/gameFolder/meta/data/font/Alphabet.hx +++ b/source/gameFolder/meta/data/font/Alphabet.hx @@ -402,6 +402,11 @@ class AlphaCharacter extends FlxSprite animation.play(letter); setGraphicSize(10, 40); y += 16; + case ",": + animation.addByPrefix(letter, 'comma', 24); + animation.play(letter); + setGraphicSize(10, 10); + y += 48; default: animation.addByPrefix(letter, letter, 24); animation.play(letter); diff --git a/source/gameFolder/meta/state/CustomTitlescreen.hx b/source/gameFolder/meta/state/CustomTitlescreen.hx index dccdd53ab..355d431bd 100644 --- a/source/gameFolder/meta/state/CustomTitlescreen.hx +++ b/source/gameFolder/meta/state/CustomTitlescreen.hx @@ -96,9 +96,13 @@ class CustomTitlescreen extends MusicBeatState add(bg); logoBl = new FlxSprite(); - logoBl.loadGraphic(Paths.image('menus/base/title/FELogo')); + logoBl.frames = Paths.getSparrowAtlas('menus/base/title/foreverlogo'); + logoBl.animation.addByPrefix('bumpin', 'forever bop', 16, false, false, false); + logoBl.animation.play('bumpin'); logoBl.antialiasing = true; + logoBl.updateHitbox(); + logoBl.setGraphicSize(Std.int(logoBl.width / 2)); logoBl.updateHitbox(); @@ -167,8 +171,6 @@ class CustomTitlescreen extends MusicBeatState logoBl.scale.x = FlxMath.lerp(newLogoScale, logoBl.scale.x, 0.95); logoBl.scale.y = FlxMath.lerp(newLogoScale, logoBl.scale.y, 0.95); - logoBl.angle = FlxMath.lerp(0, logoBl.angle, 0.95); - var pressedEnter:Bool = FlxG.keys.justPressed.ENTER; #if mobile @@ -271,16 +273,7 @@ class CustomTitlescreen extends MusicBeatState override function beatHit() { super.beatHit(); - - var increment = 1.05; - if (curBeat % 2 == 0) - increment = 1.15; - - logoBl.setGraphicSize(Std.int(initLogowidth * increment)); - logoBl.angle += increment * 1.5 * (curBeat % 4) * (reverser); - - if (curBeat % 8 == 0) - reverser = -reverser; + logoBl.animation.play('bumpin'); switch (curBeat) { diff --git a/source/gameFolder/meta/state/PlayState.hx b/source/gameFolder/meta/state/PlayState.hx index 45bd00057..ef9993e56 100644 --- a/source/gameFolder/meta/state/PlayState.hx +++ b/source/gameFolder/meta/state/PlayState.hx @@ -107,6 +107,7 @@ class PlayState extends MusicBeatState public static var camHUD:FlxCamera; public static var camGame:FlxCamera; + public static var dialogueHUD:FlxCamera; public var camDisplaceX:Float = 0; public var camDisplaceY:Float = 0; // might not use depending on result @@ -218,6 +219,7 @@ class PlayState extends MusicBeatState dadOpponent = new Character(100, 100, SONG.player2); boyfriend = new Boyfriend(770, 450, SONG.player1); + // if you want to change characters later use setCharacter() instead of new or it will break var camPos:FlxPoint = new FlxPoint(gf.getMidpoint().x - 100, boyfriend.getMidpoint().y - 100); @@ -247,6 +249,8 @@ class PlayState extends MusicBeatState add(dadOpponent); add(boyfriend); + add(stageBuild.foreground); + // force them to dance dadOpponent.dance(); gf.dance(); @@ -255,6 +259,7 @@ class PlayState extends MusicBeatState // set song position before beginning Conductor.songPosition = -(Conductor.crochet * 4); + // EVERYTHING SHOULD GO UNDER THIS, IF YOU PLAN ON SPAWNING SOMETHING LATER ADD IT TO STAGEBUILD OR FOREGROUND // darken everything but the arrows and ui via a flxsprite var darknessBG:FlxSprite = new FlxSprite(FlxG.width * -0.5, FlxG.height * -0.5).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); darknessBG.alpha = Init.trueSettings.get('Stage Darkness') * 0.01; @@ -325,6 +330,11 @@ class PlayState extends MusicBeatState uiHUD.cameras = [camHUD]; // + // create a hud over the hud camera for dialogue + dialogueHUD = new FlxCamera(); + dialogueHUD.bgColor.alpha = 0; + FlxG.cameras.add(dialogueHUD); + // call the funny intro cutscene depending on the song var freeplayOverride = true; if (isStoryMode || freeplayOverride) @@ -377,6 +387,26 @@ class PlayState extends MusicBeatState if (health > 2) health = 2; + // dialogue checks + if (dialogueBox != null && dialogueBox.alive) { + // wheee the shift closes the dialogue + if (FlxG.keys.justPressed.SHIFT) + dialogueBox.closeDialog(); + + // the change I made was just so that it would only take accept inputs + if (controls.ACCEPT && dialogueBox.textStarted) + { + FlxG.sound.play(Paths.sound('cancelMenu')); + dialogueBox.curPage += 1; + + if (dialogueBox.curPage == dialogueBox.dialogueData.dialogue.length) + dialogueBox.closeDialog() + else + dialogueBox.updateDialog(); + } + + } + // pause the game if the game is allowed to pause and enter is pressed if (FlxG.keys.justPressed.ENTER && startedCountdown && canPause) { @@ -777,7 +807,7 @@ class PlayState extends MusicBeatState // special thanks to sam, they gave me the original system which kinda inspired my idea for this new one // get the note ms timing - var noteDiff:Float = Math.abs(coolNote.strumTime - Conductor.songPosition + 4); + var noteDiff:Float = Math.abs(coolNote.strumTime - Conductor.songPosition); trace(noteDiff); // get the timing if (coolNote.strumTime < Conductor.songPosition) @@ -1070,7 +1100,7 @@ class PlayState extends MusicBeatState negative, createdColor, scoreInt); add(numScore); // hardcoded lmao - if (Init.trueSettings.get('SM-like Judgements')) + if (Init.trueSettings.get('Fixed Judgements')) { numScore.cameras = [camHUD]; numScore.x += 100; @@ -1143,7 +1173,7 @@ class PlayState extends MusicBeatState var rating = ForeverAssets.generateRating('$daRating', (daRating == 'sick' ? allSicks : false), timing, assetModifier, changeableSkin, 'UI'); add(rating); - if (Init.trueSettings.get('SM-like Judgements')) + if (Init.trueSettings.get('Fixed Judgements')) { // bound to camera rating.cameras = [camHUD]; @@ -1237,9 +1267,7 @@ class PlayState extends MusicBeatState } function sortByShit(Obj1:Note, Obj2:Note):Int - { return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime); - } function resyncVocals():Void { @@ -1256,9 +1284,7 @@ class PlayState extends MusicBeatState super.stepHit(); ///* if (songMusic.time > Conductor.songPosition + 20 || songMusic.time < Conductor.songPosition - 20) - { resyncVocals(); - } //*/ } @@ -1445,6 +1471,8 @@ class PlayState extends MusicBeatState FlxG.switchState(new PlayState()); } + var dialogueBox:DialogueBox; + public function songIntroCutscene() { switch (curSong.toLowerCase()) @@ -1478,18 +1506,31 @@ class PlayState extends MusicBeatState }); }); case 'roses': - FlxG.sound.play(Paths.sound('ANGRY')); - // schoolIntro(doof); + // the same just play angery noise LOL + FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX')); + var dialogPath = Paths.json(SONG.song.toLowerCase() + '/dialogue'); + + if (!skipCutscenes() && sys.FileSystem.exists(dialogPath)) + { + startedCountdown = false; + + dialogueBox = DialogueBox.createDialogue(sys.io.File.getContent(dialogPath)); + dialogueBox.cameras = [dialogueHUD]; + dialogueBox.whenDaFinish = startCountdown; + + add(dialogueBox); + } + else + startCountdown(); default: var dialogPath = Paths.json(SONG.song.toLowerCase() + '/dialogue'); - if (!Init.trueSettings.get('Skip Cutscenes') && sys.FileSystem.exists(dialogPath)) + if (!skipCutscenes() && sys.FileSystem.exists(dialogPath)) { startedCountdown = false; - var dialogueBox:DialogueBox; dialogueBox = DialogueBox.createDialogue(sys.io.File.getContent(dialogPath)); - dialogueBox.cameras = [camHUD]; + dialogueBox.cameras = [dialogueHUD]; dialogueBox.whenDaFinish = startCountdown; add(dialogueBox); @@ -1500,6 +1541,27 @@ class PlayState extends MusicBeatState // } + public static function skipCutscenes():Bool { + // pretty messy but an if statement is messier + if (Init.trueSettings.get('Skip Text') != null + && Std.isOfType(Init.trueSettings.get('Skip Text'), String)) { + switch (cast(Init.trueSettings.get('Skip Text'), String)) + { + case 'never': + return false; + case 'freeplay only': + if (!isStoryMode) + return true; + else + return false; + default: + return true; + } + } + + return false; + } + public static var swagCounter:Int = 0; private function startCountdown():Void diff --git a/source/gameFolder/meta/state/charting/ChartingState.hx b/source/gameFolder/meta/state/charting/ChartingState.hx index 2470c1cd9..af1ef16da 100644 --- a/source/gameFolder/meta/state/charting/ChartingState.hx +++ b/source/gameFolder/meta/state/charting/ChartingState.hx @@ -80,6 +80,8 @@ class ChartingState extends MusicBeatState private var curRenderedSustains:FlxTypedGroup; private var curRenderedSections:FlxTypedGroup; + private var arrowGroup:FlxTypedSpriteGroup; + override public function create() { // @@ -102,6 +104,8 @@ class ChartingState extends MusicBeatState curRenderedSustains = new FlxTypedGroup(); curRenderedSections = new FlxTypedGroup(); + generateNotes(); + add(curRenderedSections); add(curRenderedSustains); add(curRenderedNotes); @@ -114,6 +118,31 @@ class ChartingState extends MusicBeatState add(strumLine); strumLine.screenCenter(X); + // and now the epic note thingies + arrowGroup = new FlxTypedSpriteGroup(0, 0); + for (i in 0...keysTotal) + { + var typeReal:Int = i; + if (typeReal > 3) + typeReal -= 4; + + var newArrow:UIStaticArrow = ForeverAssets.generateUIArrows(((FlxG.width / 2) - ((keysTotal / 2) * gridSize)) + ((i - 1) * gridSize), + -76, typeReal, 'chart editor'); + + newArrow.ID = i; + newArrow.setGraphicSize(gridSize); + newArrow.updateHitbox(); + newArrow.alpha = 0.9; + newArrow.antialiasing = true; + + // lol silly idiot + newArrow.playAnim('static'); + + arrowGroup.add(newArrow); + } + add(arrowGroup); + arrowGroup.x -= 1; + // code from the playstate so I can separate the camera and hud camGame = new FlxCamera(); camHUD = new FlxCamera(); @@ -124,8 +153,13 @@ class ChartingState extends MusicBeatState FlxCamera.defaultCameras = [camGame]; FlxG.camera.follow(strumLineCam); + + FlxG.mouse.useSystemCursor = false; // Use system cursor because it's prettier + FlxG.mouse.visible = true; // Hide mouse on start } + var hitSoundsPlayed:Array = []; + override public function update(elapsed:Float) { if (FlxG.keys.justPressed.SPACE) @@ -142,7 +176,7 @@ class ChartingState extends MusicBeatState songMusic.play(); // reset note tick sounds - // hitSoundsPlayed = []; + hitSoundsPlayed = []; // playButtonAnimation('play'); } @@ -164,6 +198,7 @@ class ChartingState extends MusicBeatState strumLine.y = getYfromStrum(Conductor.songPosition); strumLineCam.y = strumLine.y + (FlxG.height / 3); + arrowGroup.y = strumLine.y; coolGradient.y = strumLineCam.y - (FlxG.height / 2); coolGrid.y = strumLineCam.y - (FlxG.height / 2); @@ -178,6 +213,19 @@ class ChartingState extends MusicBeatState ForeverTools.killMusic([songMusic, vocals]); Main.switchState(this, new PlayState()); } + + // call all rendered notes lol + curRenderedNotes.forEach(function(epicNote:Note){ + if ((epicNote.y < (strumLineCam.y - (FlxG.height / 2) - epicNote.height)) + || (epicNote.y > (strumLineCam.y + (FlxG.height / 2)))) { + // do epic note calls for strum stuffs + if (Math.floor(Conductor.songPosition / Conductor.stepCrochet) == Math.floor(epicNote.strumTime / Conductor.stepCrochet) + && (!hitSoundsPlayed.contains(epicNote))) { + + hitSoundsPlayed.push(epicNote); + } + } + }); } function getStrumTime(yPos:Float):Float @@ -209,9 +257,30 @@ class ChartingState extends MusicBeatState add(fullGrid); } + var sectionsMax = 0; + function generateNotes() { // GENERATING THE GRID NOTES! + curRenderedNotes.clear(); + curRenderedSustains.clear(); + + //sectionsMax = 1; + for (section in 0..._song.notes.length) + { + sectionsMax = section; + for (i in _song.notes[section].sectionNotes) + { + // note stuffs + var daNoteAlt = 0; + if (i.length > 2) + daNoteAlt = i[3]; + generateChartNote(i[1], i[0], i[2], daNoteAlt, section); + } + + } + // lolll + //sectionsMax--; } function loadSong(daSong:String):Void @@ -236,6 +305,7 @@ class ChartingState extends MusicBeatState if (curSong == _song) songMusic.time = songPosition; curSong = _song; + songPosition = 0; pauseMusic(); @@ -247,10 +317,10 @@ class ChartingState extends MusicBeatState // } - private function generateChartNote(daNoteInfo, daStrumTime, daSus, daNoteAlt, noteSection, curNoteMap:Map) + private function generateChartNote(daNoteInfo, daStrumTime, daSus, daNoteAlt, noteSection) { // - var note:Note = new Note(daStrumTime, daNoteInfo % 4, daNoteAlt); + var note:Note = ForeverAssets.generateArrow(PlayState.assetModifier, daStrumTime, daNoteInfo % 4, 0, daNoteAlt, false, null); // I love how there's 3 different engines that use this exact same variable name lmao note.rawNoteData = daNoteInfo; note.sustainLength = daSus; @@ -264,12 +334,10 @@ class ChartingState extends MusicBeatState note.y = Math.floor(getYfromStrum(daStrumTime)); curRenderedNotes.add(note); - - curNoteMap.set(note, null); - generateSustain(daStrumTime, daNoteInfo, daSus, daNoteAlt, note, curNoteMap); + generateSustain(daStrumTime, daNoteInfo, daSus, daNoteAlt, note); } - private function generateSustain(daStrumTime:Float = 0, daNoteInfo:Int = 0, daSus:Float = 0, daNoteAlt:Float = 0, note:Note, curNoteMap:Map) + private function generateSustain(daStrumTime:Float = 0, daNoteInfo:Int = 0, daSus:Float = 0, daNoteAlt:Float = 0, note:Note) { /* if (daSus > 0) diff --git a/source/gameFolder/meta/state/menus/OptionsMenuState.hx b/source/gameFolder/meta/state/menus/OptionsMenuState.hx index 5067913bd..d14a469c8 100644 --- a/source/gameFolder/meta/state/menus/OptionsMenuState.hx +++ b/source/gameFolder/meta/state/menus/OptionsMenuState.hx @@ -66,9 +66,7 @@ class OptionsMenuState extends MusicBeatState ['Centered Notefield', getFromOption], ['Ghost Tapping', getFromOption], ['Display Accuracy', getFromOption], - ['Skip Cutscenes', getFromOption], - ['Display Miss Count', getFromOption], - // + ['Skip Text', getFromOption], ['', null], ['Meta Settings', null], ['', null], @@ -89,7 +87,7 @@ class OptionsMenuState extends MusicBeatState ['', null], ['Disable Antialiasing', getFromOption], ['No Camera Note Movement', getFromOption], - ['SM-like Judgements', getFromOption], + ['Fixed Judgements', getFromOption], ['', null], ['Accessibility Settings', null], ['', null], @@ -382,13 +380,13 @@ class OptionsMenuState extends MusicBeatState { switch (Init.gameSettings.get(letter.text)[1]) { - case 0: + case Init.SettingTypes.Checkmark: // checkmark var checkmark = ForeverAssets.generateCheckmark(10, letter.y, 'checkboxThingie', 'base', 'default', 'UI'); checkmark.playAnim(Std.string(Init.trueSettings.get(letter.text)) + ' finished'); extrasMap.set(letter, checkmark); - case 1: + case Init.SettingTypes.Selector: // selector var selector:Selector = new Selector(10, letter.y, letter.text, Init.gameSettings.get(letter.text)[4], (letter.text == 'Framerate Cap') ? true : false, (letter.text == 'Stage Darkness') ? true : false); @@ -413,7 +411,7 @@ class OptionsMenuState extends MusicBeatState { switch (Init.gameSettings.get(activeSubgroup.members[curSelection].text)[1]) { - case 0: + case Init.SettingTypes.Checkmark: // checkmark basics lol if (controls.ACCEPT) { @@ -432,7 +430,7 @@ class OptionsMenuState extends MusicBeatState lockedMovement = false; }); } - case 1: + case Init.SettingTypes.Selector: #if !html5 var selector:Selector = currentAttachmentMap.get(activeSubgroup.members[curSelection]); @@ -512,18 +510,21 @@ class OptionsMenuState extends MusicBeatState { // get the current option as a number var storedNumber:Int = 0; - for (curOption in 0...selector.options.length) - { - if (selector.options[curOption] == selector.optionChosen.text) - storedNumber = curOption; + var newSelection:Int = storedNumber; + if (selector.options != null) { + for (curOption in 0...selector.options.length) + { + if (selector.options[curOption] == selector.optionChosen.text) + storedNumber = curOption; + } + + newSelection = storedNumber + updateBy; + if (newSelection < 0) + newSelection = selector.options.length - 1; + else if (newSelection >= selector.options.length) + newSelection = 0; } - var newSelection = storedNumber + updateBy; - if (newSelection < 0) - newSelection = selector.options.length - 1; - else if (newSelection >= selector.options.length) - newSelection = 0; - if (updateBy == -1) selector.selectorPlay('left', 'press'); else @@ -579,5 +580,6 @@ class OptionsMenuState extends MusicBeatState lockedMovement = false; }); } + // } } diff --git a/source/gameFolder/meta/subState/OptionsSubstate.hx b/source/gameFolder/meta/subState/OptionsSubstate.hx index 4ef07c2bb..edc36ccc0 100644 --- a/source/gameFolder/meta/subState/OptionsSubstate.hx +++ b/source/gameFolder/meta/subState/OptionsSubstate.hx @@ -301,17 +301,7 @@ class OptionsSubstate extends MusicBeatSubState Init.saveSettings(); // for offset super.close(); } - - /// options submenu stuffs - /// right here lol - // - // I think - // - // just a little further - // - // almost there - // - // got it! + private var submenu:FlxSprite; private function openSubmenu()