diff --git a/Project.xml b/Project.xml
index 7edddb7..08b9a5a 100644
--- a/Project.xml
+++ b/Project.xml
@@ -116,6 +116,7 @@
+
diff --git a/source/Discord.hx b/source/Discord.hx
new file mode 100644
index 0000000..9d5b103
--- /dev/null
+++ b/source/Discord.hx
@@ -0,0 +1,82 @@
+package;
+
+import Sys.sleep;
+import discord_rpc.DiscordRpc;
+
+using StringTools;
+
+class DiscordClient
+{
+ public function new()
+ {
+ trace("Discord Client starting...");
+ DiscordRpc.start({
+ clientID: "557069829501091850", // change this to what ever the fuck you want lol
+ onReady: onReady,
+ onError: onError,
+ onDisconnected: onDisconnected
+ });
+ trace("Discord Client started.");
+
+ while (true)
+ {
+ DiscordRpc.process();
+ sleep(2);
+ //trace("Discord Client Update");
+ }
+
+ DiscordRpc.shutdown();
+ }
+
+ static function onReady()
+ {
+ DiscordRpc.presence({
+ details: "In the Menus",
+ state: null,
+ largeImageKey: 'icon',
+ largeImageText: "fridaynightfunkin"
+ });
+ }
+
+ static function onError(_code:Int, _message:String)
+ {
+ trace('Error! $_code : $_message');
+ }
+
+ static function onDisconnected(_code:Int, _message:String)
+ {
+ trace('Disconnected! $_code : $_message');
+ }
+
+ public static function initialize()
+ {
+ var DiscordDaemon = sys.thread.Thread.create(() ->
+ {
+ new DiscordClient();
+ });
+ trace("Discord Client initialized");
+ }
+
+ public static function changePresence(details:String, state:Null, ?smallImageKey : String, ?hasStartTimestamp : Bool, ?endTimestamp: Float)
+ {
+ var startTimestamp:Float = if(hasStartTimestamp) Date.now().getTime() else 0;
+
+ if (endTimestamp > 0)
+ {
+ endTimestamp = startTimestamp + endTimestamp;
+ }
+
+ DiscordRpc.presence({
+ details: details,
+ state: state,
+ largeImageKey: 'icon',
+ largeImageText: "fridaynightfunkin",
+ smallImageKey : smallImageKey,
+ // Obtained times are in milliseconds so they are divided so Discord can use it
+ startTimestamp : Std.int(startTimestamp / 1000),
+ endTimestamp : Std.int(endTimestamp / 1000)
+ });
+
+ //trace('Discord RPC Updated. Arguments: $details, $state, $smallImageKey, $hasStartTimestamp, $endTimestamp');
+ }
+}
\ No newline at end of file
diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx
index 7f6b5ac..3b9b096 100644
--- a/source/FreeplayState.hx
+++ b/source/FreeplayState.hx
@@ -10,6 +10,11 @@ import flixel.text.FlxText;
import flixel.util.FlxColor;
import lime.utils.Assets;
+
+#if desktop
+import Discord.DiscordClient;
+#end
+
using StringTools;
class FreeplayState extends MusicBeatState
@@ -47,6 +52,11 @@ class FreeplayState extends MusicBeatState
}
*/
+ #if desktop
+ // Updating Discord Rich Presence
+ DiscordClient.changePresence("In the Menus", null);
+ #end
+
var isDebug:Bool = false;
#if debug
diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx
index 3ba405c..8705ba4 100644
--- a/source/MainMenuState.hx
+++ b/source/MainMenuState.hx
@@ -14,6 +14,10 @@ import flixel.util.FlxColor;
import io.newgrounds.NG;
import lime.app.Application;
+#if desktop
+import Discord.DiscordClient;
+#end
+
using StringTools;
class MainMenuState extends MusicBeatState
@@ -40,6 +44,11 @@ class MainMenuState extends MusicBeatState
override function create()
{
+ #if desktop
+ // Updating Discord Rich Presence
+ DiscordClient.changePresence("In the Menus", null);
+ #end
+
if (!FlxG.sound.music.playing)
{
FlxG.sound.playMusic(Paths.music('freakyMenu'));
diff --git a/source/PlayState.hx b/source/PlayState.hx
index b88cf80..fcef655 100644
--- a/source/PlayState.hx
+++ b/source/PlayState.hx
@@ -39,6 +39,10 @@ import openfl.display.BlendMode;
import openfl.display.StageQuality;
import openfl.filters.ShaderFilter;
+#if desktop
+import Discord.DiscordClient;
+#end
+
using StringTools;
class PlayState extends MusicBeatState
@@ -60,6 +64,15 @@ class PlayState extends MusicBeatState
var halloweenLevel:Bool = false;
+ #if desktop
+ // Discord RPC variables
+ var storyDifficultyText:String = "";
+ var iconRPC:String = "";
+ var songLength:Float = 0;
+ var detailsText:String = "";
+ var detailsPausedText:String = "";
+ #end
+
private var vocals:FlxSound;
private var dad:Character;
@@ -163,6 +176,49 @@ class PlayState extends MusicBeatState
repPresses = 0;
repReleases = 0;
+ #if desktop
+ // Making difficulty text for Discord Rich Presence.
+ switch (storyDifficulty)
+ {
+ case 0:
+ storyDifficultyText = "Easy";
+ case 1:
+ storyDifficultyText = "Normal";
+ case 2:
+ storyDifficultyText = "Hard";
+ }
+
+ iconRPC = SONG.player2;
+
+ // To avoid having duplicate images in Discord assets
+ switch (iconRPC)
+ {
+ case 'senpai-angry':
+ iconRPC = 'senpai';
+ case 'monster-christmas':
+ iconRPC = 'monster';
+ case 'mom-car':
+ iconRPC = 'mom';
+ }
+
+ // String that contains the mode defined here so it isn't necessary to call changePresence for each mode
+ if (isStoryMode)
+ {
+ detailsText = "Story Mode: Week " + storyWeek;
+ }
+ else
+ {
+ detailsText = "Freeplay";
+ }
+
+ // String for when the game is paused
+ detailsPausedText = "Paused - " + detailsText;
+
+ // Updating Discord Rich Presence.
+ DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ")", "\nAcc: " + truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
+ #end
+
+
// var gameCam:FlxCamera = FlxG.camera;
camGame = new FlxCamera();
camHUD = new FlxCamera();
@@ -1038,6 +1094,14 @@ class PlayState extends MusicBeatState
FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false);
FlxG.sound.music.onComplete = endSong;
vocals.play();
+
+ #if desktop
+ // Song duration in a float, useful for the time left feature
+ songLength = FlxG.sound.music.length;
+
+ // Updating Discord Rich Presence (with Time Left)
+ DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ")", "\nAcc: " + truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
+ #end
}
var debugNum:Int = 0;
@@ -1261,6 +1325,9 @@ class PlayState extends MusicBeatState
vocals.pause();
}
+ #if desktop
+ DiscordClient.changePresence("PAUSED on " + SONG.song + " (" + storyDifficultyText + ")", "Acc: " + truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
+ #end
if (!startTimer.finished)
startTimer.active = false;
}
@@ -1280,10 +1347,22 @@ class PlayState extends MusicBeatState
if (!startTimer.finished)
startTimer.active = true;
paused = false;
+
+ #if desktop
+ if (startTimer.finished)
+ {
+ DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ")", "\nAcc: " + truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses, iconRPC, true, songLength - Conductor.songPosition);
+ }
+ else
+ {
+ DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC);
+ }
+ #end
}
super.closeSubState();
}
+
function resyncVocals():Void
{
@@ -1293,6 +1372,10 @@ class PlayState extends MusicBeatState
Conductor.songPosition = FlxG.sound.music.time;
vocals.time = Conductor.songPosition;
vocals.play();
+
+ #if desktop
+ DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ")", "\nAcc: " + truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
+ #end
}
private var paused:Bool = false;
@@ -1364,6 +1447,9 @@ class PlayState extends MusicBeatState
if (FlxG.keys.justPressed.SEVEN)
{
+ #if desktop
+ DiscordClient.changePresence("Chart Editor", null, null, true);
+ #end
FlxG.switchState(new ChartingState());
}
@@ -1550,6 +1636,11 @@ class PlayState extends MusicBeatState
openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ #if desktop
+ // Game Over doesn't get his own variable because it's only used here
+ DiscordClient.changePresence(detailsText, "GAME OVER -- " + SONG.song + " (" + storyDifficultyText + ")\nAcc: " + truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
+ #end
+
// FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
}
@@ -2570,6 +2661,19 @@ class PlayState extends MusicBeatState
{
// dad.dance();
}
+
+
+ // yes this updates every step.
+ // yes this is bad
+ // but i'm doing it to update misses and accuracy
+ #if desktop
+ // Song duration in a float, useful for the time left feature
+ songLength = FlxG.sound.music.length;
+
+ // Updating Discord Rich Presence (with Time Left)
+ DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ")", "Acc: " + truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC,true, songLength - Conductor.songPosition);
+ #end
+
}
var lightningStrikeBeat:Int = 0;
diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx
index 1e27eed..9957c18 100644
--- a/source/StoryMenuState.hx
+++ b/source/StoryMenuState.hx
@@ -13,6 +13,10 @@ import flixel.util.FlxColor;
import flixel.util.FlxTimer;
import lime.net.curl.CURLCode;
+#if desktop
+import Discord.DiscordClient;
+#end
+
using StringTools;
class StoryMenuState extends MusicBeatState
@@ -70,6 +74,11 @@ class StoryMenuState extends MusicBeatState
override function create()
{
+ #if desktop
+ // Updating Discord Rich Presence
+ DiscordClient.changePresence("In the Menus", null);
+ #end
+
transIn = FlxTransitionableState.defaultTransIn;
transOut = FlxTransitionableState.defaultTransOut;
diff --git a/source/TitleState.hx b/source/TitleState.hx
index 046d4ab..d27a84b 100644
--- a/source/TitleState.hx
+++ b/source/TitleState.hx
@@ -24,6 +24,11 @@ import io.newgrounds.NG;
import lime.app.Application;
import openfl.Assets;
+#if desktop
+import Discord.DiscordClient;
+import sys.thread.Thread;
+#end
+
using StringTools;
class TitleState extends MusicBeatState
@@ -51,8 +56,13 @@ class TitleState extends MusicBeatState
sys.FileSystem.createDirectory(Sys.getCwd() + "\\assets\\replays");
#end
+
PlayerSettings.init();
+ #if desktop
+ DiscordClient.initialize();
+ #end
+
curWacky = FlxG.random.getObject(getIntroTextShit());
// DEBUG BULLSHIT