From 7dc874d622236591234de906b9134152a22a02bd Mon Sep 17 00:00:00 2001
From: Brandon <brandy@scarecrowarts.com>
Date: Fri, 6 Nov 2020 21:17:27 -0500
Subject: [PATCH] caught up to cam

---
 CHANGELOG.md                | 41 ++++++++++++----
 Project.xml                 | 12 +++--
 source/ChartingState.hx     |  9 ++++
 source/FreeplayState.hx     | 97 +++++++++++++++++++++++++++++++++++--
 source/Highscore.hx         | 85 ++++++++++++++++++++++++++++++++
 source/MainMenuState.hx     | 13 ++++-
 source/MenuItem.hx          | 13 ++---
 source/MusicBeatSubstate.hx |  1 +
 source/NGio.hx              |  9 ++++
 source/OptionsMenu.hx       | 29 +++++++++++
 source/OptionsSubState.hx   | 11 +++++
 source/PlayState.hx         | 35 ++++++-------
 source/StoryMenuState.hx    | 42 ++++++++++------
 source/TitleState.hx        | 38 +++++++++------
 14 files changed, 360 insertions(+), 75 deletions(-)
 create mode 100644 source/Highscore.hx
 create mode 100644 source/OptionsMenu.hx
 create mode 100644 source/OptionsSubState.hx

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 875bc460f..94888a81d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,16 +1,37 @@
 # Changelog
 All notable changes will be documented in this file.
 
-## [1.1.0]
-### Added
-- 32bit support
-- Controller (dancepads) support
-- Pause screen
-- Main Menu overhaul
-- Cool intro screen thing
-- Uh lots of bullshit
-- Remind me to actually add this later lmaooo
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [1.0.0] - 2020-10-05
+## [0.2.1.2] - 2020-11-06
+### Fixed
+- Story mode scores not properly resetting, leading to VERY inflated highscores on the leaderboards. This also requires me to clear the scores that are on the leaderboard right now, sorry!
+- Difficulty on storymode and in freeplay scores
+
+## [0.2.1.1] - 2020-11-06
+### Fixed
+- Week 2 not unlocking properly
+
+## [0.2.1] - 2020-11-06
+### Added
+- Scores to the freeplay menu
+- A few new intro boot messages.
+- Lightning effect in Spooky stages
+- Campaign scores, can now compete on scoreboards for campaign!
+- Can now change difficulties in Freeplay mode
+
+### Changed
+- Balanced out Normal mode for the harder songs(Dadbattle and Spookeez, not South yet). Should be much easier all around.
+- Put tutorial in it's own 'week', so that if you want to play week 1, you don't have to play the tutorial.
+
+### Fixed
+- One of the charting bits on South and Spookeez during the intro.
+
+## [0.2.0] - 2020-11-01
+### Added
+- Uhh Newgrounds release lolol I always lose track of shit.
+
+## [0.1.0] - 2020-10-05
 ### Added
 - Uh, everything. This the game's initial gamejam release. We put it out
\ No newline at end of file
diff --git a/Project.xml b/Project.xml
index a947bbb18..5da40d92f 100644
--- a/Project.xml
+++ b/Project.xml
@@ -2,7 +2,7 @@
 <project>
 	<!-- _________________________ Application Settings _________________________ -->
 
-	<app title="Friday Night Funkin" file="Funkin" packageName="com.ninjamuffin99.funkin" main="Main" version="0.0.1" company="ninjamuffin99" />
+	<app title="Friday Night Funkin" file="Funkin" packageName="com.ninjamuffin99.funkin" main="Main" version="0.2.1.2" company="ninjamuffin99" />
 
 	<!--The flixel preloader is not accurate in Chrome. You can use it regularly if you embed the swf into a html file
 		or you can set the actual size of your file manually at "FlxPreloaderBase-onUpdate-bytesTotal"-->
@@ -45,8 +45,9 @@
 	<assets path="assets/sounds" include="*.mp3" if="web" />
 	<assets path="assets/sounds" include="*.ogg" unless="web" />
 
-	<assets path="assets/fonts/vcr.ttf" embed="true" />
+	<assets path="CHANGELOG.md"/>
 
+	<assets path="assets/fonts/vcr.ttf" embed="true" />
 
 	<!-- _______________________________ Libraries ______________________________ -->
 
@@ -58,6 +59,9 @@
 
 	<!--In case you want to use the ui package-->
 	<haxelib name="flixel-ui" />
+	<haxelib name="newgrounds" />
+	<haxelib name="markdown" />
+	<haxelib name="HtmlParser" />
 
 	<!--In case you want to use nape with flixel-->
 	<!--<haxelib name="nape-haxe4" />-->
@@ -100,7 +104,5 @@
 
 	<icon path="art/icon.png" />
 	<!-- <haxedef name="SKIP_TO_PLAYSTATE" if="debug" /> -->
-	<haxedef name="NG_LOGIN" />
-
-
+	<haxedef name="NG_LOGIN" if="newgrounds" />
 </project>
diff --git a/source/ChartingState.hx b/source/ChartingState.hx
index 070d55597..deeb34924 100644
--- a/source/ChartingState.hx
+++ b/source/ChartingState.hx
@@ -28,7 +28,9 @@ import openfl.events.Event;
 import openfl.events.IOErrorEvent;
 import openfl.events.IOErrorEvent;
 import openfl.events.IOErrorEvent;
+import openfl.media.Sound;
 import openfl.net.FileReference;
+import openfl.utils.ByteArray;
 
 using StringTools;
 
@@ -762,6 +764,13 @@ class ChartingState extends MusicBeatState
 		FlxG.resetState();
 	}
 
+	var mp3File:Sound;
+	var waveForm:FlxSprite;
+
+	function drawWave():Void
+	{
+	}
+
 	private function saveLevel()
 	{
 		var json = {
diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx
index 193744704..ad336ce8a 100644
--- a/source/FreeplayState.hx
+++ b/source/FreeplayState.hx
@@ -1,10 +1,15 @@
 package;
 
+import flash.text.TextField;
 import flixel.FlxG;
 import flixel.FlxSprite;
 import flixel.addons.display.FlxGridOverlay;
 import flixel.group.FlxGroup.FlxTypedGroup;
+import flixel.math.FlxMath;
 import flixel.text.FlxText;
+import flixel.util.FlxColor;
+import htmlparser.HtmlDocument;
+import lime.utils.Assets;
 
 class FreeplayState extends MusicBeatState
 {
@@ -12,13 +17,22 @@ class FreeplayState extends MusicBeatState
 
 	var selector:FlxText;
 	var curSelected:Int = 0;
+	var curDifficulty:Int = 1;
+
+	var scoreText:FlxText;
+	var diffText:FlxText;
+	var lerpScore:Int = 0;
+	var intendedScore:Int = 0;
 
 	private var grpSongs:FlxTypedGroup<Alphabet>;
 
 	override function create()
 	{
-		if (!FlxG.sound.music.playing)
-			FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt);
+		if (FlxG.sound.music != null)
+		{
+			if (!FlxG.sound.music.playing)
+				FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt);
+		}
 
 		var isDebug:Bool = false;
 
@@ -53,7 +67,23 @@ class FreeplayState extends MusicBeatState
 			// songText.screenCenter(X);
 		}
 
+		scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32);
+		// scoreText.autoSize = false;
+		scoreText.setFormat("assets/fonts/vcr.ttf", 32, FlxColor.WHITE, RIGHT);
+		// scoreText.alignment = RIGHT;
+
+		var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000);
+		scoreBG.alpha = 0.6;
+		add(scoreBG);
+
+		diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24);
+		diffText.font = scoreText.font;
+		add(diffText);
+
+		add(scoreText);
+
 		changeSelection();
+		changeDiff();
 
 		// FlxG.sound.playMusic('assets/music/title' + TitleState.soundExt, 0);
 		// FlxG.sound.music.fadeIn(2, 0, 0.8);
@@ -65,12 +95,33 @@ class FreeplayState extends MusicBeatState
 
 		var swag:Alphabet = new Alphabet(1, 0, "swag");
 
+		// JUST DOIN THIS SHIT FOR TESTING!!!
+		/* 
+			var md:String = Markdown.markdownToHtml(Assets.getText('CHANGELOG.md'));
+
+			var texFel:TextField = new TextField();
+			texFel.width = FlxG.width;
+			texFel.height = FlxG.height;
+			// texFel.
+			texFel.htmlText = md;
+
+			FlxG.stage.addChild(texFel);
+
+			// scoreText.textField.htmlText = md;
+
+			trace(md);
+		 */
+
 		super.create();
 	}
 
 	override function update(elapsed:Float)
 	{
 		super.update(elapsed);
+
+		lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4));
+		scoreText.text = "PERSONAL BEST:" + lerpScore;
+
 		var upP = controls.UP_P;
 		var downP = controls.DOWN_P;
 		var accepted = controls.ACCEPT;
@@ -84,6 +135,11 @@ class FreeplayState extends MusicBeatState
 			changeSelection(1);
 		}
 
+		if (controls.LEFT_P)
+			changeDiff(-1);
+		if (controls.RIGHT_P)
+			changeDiff(1);
+
 		if (controls.BACK)
 		{
 			FlxG.switchState(new MainMenuState());
@@ -91,15 +147,45 @@ class FreeplayState extends MusicBeatState
 
 		if (accepted)
 		{
-			PlayState.SONG = Song.loadFromJson(songs[curSelected].toLowerCase(), songs[curSelected].toLowerCase());
+			var poop:String = Highscore.formatSong(songs[curSelected].toLowerCase(), curDifficulty);
+
+			trace(poop);
+
+			PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].toLowerCase());
 			PlayState.isStoryMode = false;
+			PlayState.storyDifficulty = curDifficulty;
 			FlxG.switchState(new PlayState());
-			FlxG.sound.music.stop();
+			if (FlxG.sound.music != null)
+				FlxG.sound.music.stop();
+		}
+	}
+
+	function changeDiff(change:Int = 0)
+	{
+		curDifficulty += change;
+
+		if (curDifficulty < 0)
+			curDifficulty = 2;
+		if (curDifficulty > 2)
+			curDifficulty = 0;
+
+		intendedScore = Highscore.getScore(songs[curSelected], curDifficulty);
+
+		switch (curDifficulty)
+		{
+			case 0:
+				diffText.text = "EASY";
+			case 1:
+				diffText.text = 'NORMAL';
+			case 2:
+				diffText.text = "HARD";
 		}
 	}
 
 	function changeSelection(change:Int = 0)
 	{
+		NGio.logEvent('Fresh');
+
 		curSelected += change;
 
 		if (curSelected < 0)
@@ -109,6 +195,9 @@ class FreeplayState extends MusicBeatState
 
 		// selector.y = (70 * curSelected) + 30;
 
+		intendedScore = Highscore.getScore(songs[curSelected], curDifficulty);
+		// lerpScore = 0;
+
 		var bullShit:Int = 0;
 
 		for (item in grpSongs.members)
diff --git a/source/Highscore.hx b/source/Highscore.hx
new file mode 100644
index 000000000..b57870518
--- /dev/null
+++ b/source/Highscore.hx
@@ -0,0 +1,85 @@
+package;
+
+import flixel.FlxG;
+
+class Highscore
+{
+	public static var songScores:Map<String, Int> = new Map();
+
+	public static function saveScore(song:String, score:Int = 0, ?diff:Int = 0):Void
+	{
+		var daSong:String = formatSong(song, diff);
+
+		NGio.postScore(score, song);
+
+		if (songScores.exists(daSong))
+		{
+			if (songScores.get(daSong) < score)
+				setScore(daSong, score);
+		}
+		else
+			setScore(daSong, score);
+	}
+
+	public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void
+	{
+		NGio.postScore(score, "Week " + week);
+
+		var daWeek:String = formatSong('week' + week, diff);
+
+		if (songScores.exists(daWeek))
+		{
+			if (songScores.get(daWeek) < score)
+				setScore(daWeek, score);
+		}
+		else
+			setScore(daWeek, score);
+	}
+
+	/**
+	 * YOU SHOULD FORMAT SONG WITH formatSong() BEFORE TOSSING IN SONG VARIABLE
+	 */
+	static function setScore(song:String, score:Int):Void
+	{
+		// Reminder that I don't need to format this song, it should come formatted!
+		songScores.set(song, score);
+		FlxG.save.data.songScores = songScores;
+		FlxG.save.flush();
+	}
+
+	public static function formatSong(song:String, diff:Int):String
+	{
+		var daSong:String = song;
+
+		if (diff == 0)
+			daSong += '-easy';
+		else if (diff == 2)
+			daSong += '-hard';
+
+		return daSong;
+	}
+
+	public static function getScore(song:String, diff:Int):Int
+	{
+		if (!songScores.exists(formatSong(song, diff)))
+			setScore(formatSong(song, diff), 0);
+
+		return songScores.get(formatSong(song, diff));
+	}
+
+	public static function getWeekScore(week:Int, diff:Int):Int
+	{
+		if (!songScores.exists(formatSong('week' + week, diff)))
+			setScore(formatSong('week' + week, diff), 0);
+
+		return songScores.get(formatSong('week' + week, diff));
+	}
+
+	public static function load():Void
+	{
+		if (FlxG.save.data.songScores != null)
+		{
+			songScores = FlxG.save.data.songScores;
+		}
+	}
+}
diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx
index 4fd7decdd..6f2ff630d 100644
--- a/source/MainMenuState.hx
+++ b/source/MainMenuState.hx
@@ -6,8 +6,11 @@ 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 lime.app.Application;
 
 class MainMenuState extends MusicBeatState
 {
@@ -40,7 +43,7 @@ class MainMenuState extends MusicBeatState
 		camFollow = new FlxObject(0, 0, 1, 1);
 		add(camFollow);
 
-		magenta = new FlxSprite(-80).loadGraphic(AssetPaths.menuBGMagenta__png);
+		magenta = new FlxSprite(-80).loadGraphic(AssetPaths.menuDesat__png);
 		magenta.scrollFactor.x = 0;
 		magenta.scrollFactor.y = 0.18;
 		magenta.setGraphicSize(Std.int(magenta.width * 1.1));
@@ -48,6 +51,7 @@ class MainMenuState extends MusicBeatState
 		magenta.screenCenter();
 		magenta.visible = false;
 		magenta.antialiasing = true;
+		magenta.color = 0xFFfd719b;
 		add(magenta);
 		// magenta.scrollFactor.set();
 
@@ -72,6 +76,11 @@ class MainMenuState extends MusicBeatState
 
 		FlxG.camera.follow(camFollow, null, 0.06);
 
+		var versionShit:FlxText = new FlxText(5, FlxG.height - 18, 0, "v" + Application.current.meta.get('version'));
+		versionShit.scrollFactor.set();
+		versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
+		add(versionShit);
+
 		changeItem();
 
 		super.create();
@@ -137,6 +146,8 @@ class MainMenuState extends MusicBeatState
 										FlxG.switchState(new StoryMenuState());
 									case 'freeplay':
 										FlxG.switchState(new FreeplayState());
+									case 'options':
+										FlxG.switchState(new OptionsMenu());
 								}
 							});
 						}
diff --git a/source/MenuItem.hx b/source/MenuItem.hx
index 5aae4ee28..e5bf62c9e 100644
--- a/source/MenuItem.hx
+++ b/source/MenuItem.hx
@@ -10,7 +10,7 @@ class MenuItem extends FlxSpriteGroup
 	public var targetY:Float = 0;
 	public var week:FlxSprite;
 
-	public function new(x:Float, y:Float, weekNum:Int = 0, unlocked:Bool = false)
+	public function new(x:Float, y:Float, weekNum:Int = 0)
 	{
 		super(x, y);
 
@@ -18,18 +18,15 @@ class MenuItem extends FlxSpriteGroup
 
 		week = new FlxSprite();
 		week.frames = tex;
-		week.animation.addByPrefix('week0', "WEEK1 select", 24);
-		week.animation.addByPrefix('week1', "week2 select", 24);
+		// TUTORIAL IS WEEK 0
+		week.animation.addByPrefix('week0', 'tutorial selected', 24);
+		week.animation.addByPrefix('week1', "WEEK1 select", 24);
+		week.animation.addByPrefix('week2', "week2 select", 24);
 		add(week);
 
 		week.animation.play('week' + weekNum);
 		week.animation.pause();
 		week.updateHitbox();
-
-		if (!unlocked)
-		{
-			week.alpha = 0.6;
-		}
 	}
 
 	override function update(elapsed:Float)
diff --git a/source/MusicBeatSubstate.hx b/source/MusicBeatSubstate.hx
index 0e452e9cd..511f597a7 100644
--- a/source/MusicBeatSubstate.hx
+++ b/source/MusicBeatSubstate.hx
@@ -1,5 +1,6 @@
 package;
 
+import flixel.FlxG;
 import flixel.FlxSubState;
 
 class MusicBeatSubstate extends FlxSubState
diff --git a/source/NGio.hx b/source/NGio.hx
index f90bca4c4..2073c073b 100644
--- a/source/NGio.hx
+++ b/source/NGio.hx
@@ -146,6 +146,15 @@ class NGio
 		// NGio.scoreboardArray = NG.core.scoreBoards.get(8004).scores;
 	}
 
+	inline static public function logEvent(event:String)
+	{
+		if (isLoggedIn)
+		{
+			NG.core.calls.event.logEvent(event);
+			trace('should have logged: ' + event);
+		}
+	}
+
 	inline static public function unlockMedal(id:Int)
 	{
 		if (isLoggedIn)
diff --git a/source/OptionsMenu.hx b/source/OptionsMenu.hx
new file mode 100644
index 000000000..c79c3ec70
--- /dev/null
+++ b/source/OptionsMenu.hx
@@ -0,0 +1,29 @@
+package;
+
+import flixel.FlxG;
+import flixel.FlxSprite;
+import flixel.util.FlxColor;
+
+class OptionsMenu extends MusicBeatState
+{
+	override function create()
+	{
+		var menuBG:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.menuDesat__png);
+		menuBG.color = 0xFFea71fd;
+		menuBG.setGraphicSize(Std.int(menuBG.width * 1.1));
+		menuBG.updateHitbox();
+		menuBG.screenCenter();
+		menuBG.antialiasing = true;
+		add(menuBG);
+
+		super.create();
+	}
+
+	override function update(elapsed:Float)
+	{
+		if (controls.BACK)
+			FlxG.switchState(new MainMenuState());
+
+		super.update(elapsed);
+	}
+}
diff --git a/source/OptionsSubState.hx b/source/OptionsSubState.hx
new file mode 100644
index 000000000..1995b868a
--- /dev/null
+++ b/source/OptionsSubState.hx
@@ -0,0 +1,11 @@
+package;
+
+class OptionsSubState extends MusicBeatSubstate
+{
+	var textMenuItems:Array<String> = ['Master Volume', 'Sound Volume'];
+
+	public function new()
+	{
+		super();
+	}
+}
diff --git a/source/PlayState.hx b/source/PlayState.hx
index e65bfa35a..87a435f22 100644
--- a/source/PlayState.hx
+++ b/source/PlayState.hx
@@ -37,6 +37,7 @@ class PlayState extends MusicBeatState
 	public static var curLevel:String = 'Tutorial';
 	public static var SONG:SwagSong;
 	public static var isStoryMode:Bool = false;
+	public static var storyWeek:Int = 0;
 	public static var storyPlaylist:Array<String> = [];
 	public static var storyDifficulty:Int = 1;
 
@@ -83,6 +84,8 @@ class PlayState extends MusicBeatState
 	var talking:Bool = true;
 	var songScore:Int = 0;
 
+	public static var campaignScore:Int = 0;
+
 	override public function create()
 	{
 		// var gameCam:FlxCamera = FlxG.camera;
@@ -460,7 +463,7 @@ class PlayState extends MusicBeatState
 			daBeats += 1;
 		}
 
-		trace(unspawnNotes.length);
+		// trace(unspawnNotes.length);
 		// playerCounter += 1;
 
 		unspawnNotes.sort(sortByShit);
@@ -562,7 +565,7 @@ class PlayState extends MusicBeatState
 		{
 			if (FlxG.sound.music != null)
 			{
-				vocals.time = FlxG.sound.music.time;
+				vocals.time = Conductor.songPosition;
 
 				FlxG.sound.music.play();
 				vocals.play();
@@ -602,9 +605,9 @@ class PlayState extends MusicBeatState
 			openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
 		}
 
-		if (FlxG.keys.justPressed.ESCAPE)
+		if (FlxG.keys.justPressed.SEVEN)
 		{
-			// FlxG.switchState(new ChartingState());
+			FlxG.switchState(new ChartingState());
 		}
 
 		// FlxG.watch.addQuick('VOL', vocals.amplitudeLeft);
@@ -641,8 +644,7 @@ class PlayState extends MusicBeatState
 		}
 		else
 		{
-			//Conductor.songPosition = FlxG.sound.music.time;
-			Conductor.songPosition += FlxG.elapsed * 1000;
+			Conductor.songPosition = FlxG.sound.music.time;
 
 			if (!paused)
 			{
@@ -812,6 +814,7 @@ class PlayState extends MusicBeatState
 				}
 
 				daNote.y = (strumLine.y - (Conductor.songPosition - daNote.strumTime) * (0.45 * PlayState.SONG.speed));
+
 				// WIP interpolation shit? Need to fix the pause issue
 				// daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed));
 
@@ -838,16 +841,12 @@ class PlayState extends MusicBeatState
 
 	function endSong():Void
 	{
-		trace('SONG DONE' + isStoryMode);
-
-
-		#if !switch
-		NGio.postScore(songScore, SONG.song);
-		#end
-
+		Highscore.saveScore(SONG.song, songScore, storyDifficulty);
 
 		if (isStoryMode)
 		{
+			campaignScore += songScore;
+
 			storyPlaylist.remove(storyPlaylist[0]);
 
 			if (storyPlaylist.length <= 0)
@@ -856,12 +855,12 @@ class PlayState extends MusicBeatState
 
 				FlxG.switchState(new StoryMenuState());
 
-				StoryMenuState.weekUnlocked[1] = true;
+				StoryMenuState.weekUnlocked[2] = true;
 
 				#if !switch
 				NGio.unlockMedal(60961);
 				#end
-
+				Highscore.saveWeekScore(storyWeek, campaignScore, storyDifficulty);
 
 				FlxG.save.data.weekUnlocked = StoryMenuState.weekUnlocked;
 				FlxG.save.flush();
@@ -1041,7 +1040,6 @@ class PlayState extends MusicBeatState
 				if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate)
 				{
 					possibleNotes.push(daNote);
-					trace('NOTE-' + daNote.strumTime + ' ADDED');
 				}
 			});
 
@@ -1234,7 +1232,6 @@ class PlayState extends MusicBeatState
 
 	function noteCheck(keyP:Bool, note:Note):Void
 	{
-		trace(note.noteData + ' note check here ' + keyP);
 		if (keyP)
 			goodNoteHit(note);
 		else
@@ -1304,9 +1301,9 @@ class PlayState extends MusicBeatState
 			if (vocals.time > Conductor.songPosition + Conductor.stepCrochet
 				|| vocals.time < Conductor.songPosition - Conductor.stepCrochet)
 			{
-				//vocals.pause();
+				vocals.pause();
 				vocals.time = Conductor.songPosition;
-				//vocals.play();
+				vocals.play();
 			}
 		}
 
diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx
index d88ab4833..0f4b5c018 100644
--- a/source/StoryMenuState.hx
+++ b/source/StoryMenuState.hx
@@ -5,6 +5,7 @@ import flixel.FlxSprite;
 import flixel.graphics.frames.FlxAtlasFrames;
 import flixel.group.FlxGroup.FlxTypedGroup;
 import flixel.group.FlxGroup;
+import flixel.math.FlxMath;
 import flixel.text.FlxText;
 import flixel.tweens.FlxTween;
 import flixel.util.FlxTimer;
@@ -16,12 +17,12 @@ class StoryMenuState extends MusicBeatState
 {
 	var scoreText:FlxText;
 
-	var weekData:Array<Dynamic> = [['Tutorial', 'Bopeebo', 'Fresh', 'Dadbattle'], ['Spookeez', 'South']];
+	var weekData:Array<Dynamic> = [['Tutorial'], ['Bopeebo', 'Fresh', 'Dadbattle'], ['Spookeez', 'South']];
 	var curDifficulty:Int = 1;
 
-	public static var weekUnlocked:Array<Bool> = [true, false];
+	public static var weekUnlocked:Array<Bool> = [true, true, false];
 
-	var weekCharacters:Array<Dynamic> = [['dad', 'bf', 'gf'], ['spooky', 'bf', 'gf']];
+	var weekCharacters:Array<Dynamic> = [['dad', 'bf', 'gf'], ['dad', 'bf', 'gf'], ['spooky', 'bf', 'gf']];
 	var curWeek:Int = 0;
 
 	var txtTracklist:FlxText;
@@ -38,8 +39,11 @@ class StoryMenuState extends MusicBeatState
 
 	override function create()
 	{
-		if (!FlxG.sound.music.playing)
-			FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt);
+		if (FlxG.sound.music != null)
+		{
+			if (!FlxG.sound.music.playing)
+				FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt);
+		}
 
 		persistentUpdate = persistentDraw = true;
 
@@ -65,12 +69,7 @@ class StoryMenuState extends MusicBeatState
 
 		for (i in 0...weekData.length)
 		{
-			var unlocked:Bool = true;
-
-			if (i == 1)
-				unlocked = false;
-
-			var weekThing:MenuItem = new MenuItem(0, yellowBG.y + yellowBG.height + 10, i, unlocked);
+			var weekThing:MenuItem = new MenuItem(0, yellowBG.y + yellowBG.height + 10, i);
 			weekThing.y += ((weekThing.height + 20) * i);
 			weekThing.targetY = i;
 			grpWeekText.add(weekThing);
@@ -79,6 +78,7 @@ class StoryMenuState extends MusicBeatState
 			weekThing.antialiasing = true;
 			// weekThing.updateHitbox();
 
+			// Needs an offset thingie
 			if (!weekUnlocked[i])
 			{
 				var lock:FlxSprite = new FlxSprite(weekThing.width + 10 + weekThing.x);
@@ -117,7 +117,7 @@ class StoryMenuState extends MusicBeatState
 		difficultySelectors = new FlxGroup();
 		add(difficultySelectors);
 
-		leftArrow = new FlxSprite(grpWeekText.members[0].x + 370, grpWeekText.members[0].y + 10);
+		leftArrow = new FlxSprite(grpWeekText.members[0].x + grpWeekText.members[0].width + 10, grpWeekText.members[0].y + 10);
 		leftArrow.frames = ui_tex;
 		leftArrow.animation.addByPrefix('idle', "arrow left");
 		leftArrow.animation.addByPrefix('press', "arrow push left");
@@ -150,7 +150,7 @@ class StoryMenuState extends MusicBeatState
 		txtTracklist.color = 0xFFe55777;
 		add(txtTracklist);
 		// add(rankText);
-		// add(scoreText);
+		add(scoreText);
 
 		updateText();
 
@@ -160,7 +160,9 @@ class StoryMenuState extends MusicBeatState
 	override function update(elapsed:Float)
 	{
 		// scoreText.setFormat('VCR OSD Mono', 32);
-		// scoreText.text = "Score SHIT";
+		lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.5));
+
+		scoreText.text = "WEEK SCORE:" + lerpScore;
 		// FlxG.watch.addQuick('font', scoreText.font);
 
 		difficultySelectors.visible = weekUnlocked[curWeek];
@@ -245,6 +247,8 @@ class StoryMenuState extends MusicBeatState
 			PlayState.storyDifficulty = curDifficulty;
 
 			PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + diffic, PlayState.storyPlaylist[0].toLowerCase());
+			PlayState.storyWeek = curWeek;
+			PlayState.campaignScore = 0;
 			new FlxTimer().start(1, function(tmr:FlxTimer)
 			{
 				if (FlxG.sound.music != null)
@@ -282,10 +286,14 @@ class StoryMenuState extends MusicBeatState
 
 		// USING THESE WEIRD VALUES SO THAT IT DOESNT FLOAT UP
 		sprDifficulty.y = leftArrow.y - 15;
+		intendedScore = Highscore.getWeekScore(curWeek, curDifficulty);
 
 		FlxTween.tween(sprDifficulty, {y: leftArrow.y + 15, alpha: 1}, 0.07);
 	}
 
+	var lerpScore:Int = 0;
+	var intendedScore:Int = 0;
+
 	function changeWeek(change:Int = 0):Void
 	{
 		curWeek += change;
@@ -300,6 +308,10 @@ class StoryMenuState extends MusicBeatState
 		for (item in grpWeekText.members)
 		{
 			item.targetY = bullShit - curWeek;
+			if (item.targetY == Std.int(0) && weekUnlocked[curWeek])
+				item.alpha = 1;
+			else
+				item.alpha = 0.6;
 			bullShit++;
 		}
 
@@ -326,5 +338,7 @@ class StoryMenuState extends MusicBeatState
 
 		txtTracklist.screenCenter(X);
 		txtTracklist.x -= FlxG.width * 0.35;
+
+		intendedScore = Highscore.getWeekScore(curWeek, curDifficulty);
 	}
 }
diff --git a/source/TitleState.hx b/source/TitleState.hx
index 699de8a54..f4d3274aa 100644
--- a/source/TitleState.hx
+++ b/source/TitleState.hx
@@ -36,13 +36,13 @@ class TitleState extends MusicBeatState
 		['Ritz dx', 'rest in peace'], ['rate five', 'pls no blam'], ['rhythm gaming', 'ultimate'], ['game of the year', 'forever'],
 		['you already know', 'we really out here'], ['rise and grind', 'love to luis'], ['like parappa', 'but cooler'],
 		['album of the year', 'chuckie finster'], ["free gitaroo man", "with love to wandaboy"], ['better than geometry dash', 'fight me robtop'],
-		['kiddbrute for president', 'vote now']];
+		['kiddbrute for president', 'vote now'], ['play dead estate', 'on newgrounds'], ['this is a god damn prototype', 'we workin on it okay'],
+		['WOMEN ARE real', 'this is official']];
 
 	var curWacky:Array<String> = [];
 
 	var wackyImage:FlxSprite;
 
-
 	override public function create():Void
 	{
 		#if (!web)
@@ -57,11 +57,22 @@ class TitleState extends MusicBeatState
 
 		super.create();
 
-
 		#if (!switch && !debug && NG_LOGIN)
 		var ng:NGio = new NGio(APIStuff.API, APIStuff.EncKey);
 		#end
 
+		FlxG.save.bind('funkin', 'ninjamuffin99');
+
+		Highscore.load();
+
+		if (FlxG.save.data.weekUnlocked != null)
+		{
+			StoryMenuState.weekUnlocked = FlxG.save.data.weekUnlocked;
+
+			if (StoryMenuState.weekUnlocked.length < 3)
+				StoryMenuState.weekUnlocked.insert(0, true);
+		}
+
 		#if SKIP_TO_PLAYSTATE
 		FlxG.switchState(new StoryMenuState());
 		#else
@@ -76,10 +87,6 @@ class TitleState extends MusicBeatState
 
 	function startIntro()
 	{
-		#if switch
-		initialized = true;
-		#end
-
 		if (!initialized)
 		{
 			var diamond:FlxGraphic = FlxGraphic.fromClass(GraphicTransTileDiamond);
@@ -100,13 +107,6 @@ class TitleState extends MusicBeatState
 			FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt, 0);
 
 			FlxG.sound.music.fadeIn(4, 0, 0.7);
-
-			FlxG.save.bind('funkin', 'ninjamuffin99');
-
-			if (FlxG.save.data.weekUnlocked != null)
-			{
-				StoryMenuState.weekUnlocked = FlxG.save.data.weekUnlocked;
-			}
 		}
 
 		Conductor.changeBPM(102);
@@ -192,6 +192,12 @@ class TitleState extends MusicBeatState
 	override function update(elapsed:Float)
 	{
 		Conductor.songPosition = FlxG.sound.music.time;
+		// FlxG.watch.addQuick('amp', FlxG.sound.music.amplitude);
+
+		if (FlxG.keys.justPressed.F)
+		{
+			FlxG.fullscreen = !FlxG.fullscreen;
+		}
 
 		var pressedEnter:Bool = FlxG.keys.justPressed.ENTER;
 
@@ -212,6 +218,10 @@ class TitleState extends MusicBeatState
 		{
 			#if !switch
 			NGio.unlockMedal(60960);
+
+			// If it's Friday according to da clock
+			if (Date.now().getDay() == 5)
+				NGio.unlockMedal(61034);
 			#end
 
 			titleText.animation.play('press');