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()