add experimental discord rich presence support
This commit is contained in:
parent
1810bf6d5b
commit
3dbe56690a
|
@ -37,7 +37,7 @@ category = "Game"
|
||||||
osx_minimum_system_version = "10.12"
|
osx_minimum_system_version = "10.12"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["default-base", "backend-sdl", "render-opengl", "exe", "webbrowser"]
|
default = ["default-base", "backend-sdl", "render-opengl", "exe", "webbrowser", "discord-rpc"]
|
||||||
default-base = ["ogg-playback"]
|
default-base = ["ogg-playback"]
|
||||||
ogg-playback = ["lewton"]
|
ogg-playback = ["lewton"]
|
||||||
backend-sdl = ["sdl2", "sdl2-sys"]
|
backend-sdl = ["sdl2", "sdl2-sys"]
|
||||||
|
@ -45,6 +45,7 @@ backend-glutin = ["winit", "glutin", "render-opengl"]
|
||||||
backend-horizon = []
|
backend-horizon = []
|
||||||
render-opengl = []
|
render-opengl = []
|
||||||
scripting-lua = ["lua-ffi"]
|
scripting-lua = ["lua-ffi"]
|
||||||
|
discord-rpc = []
|
||||||
netplay = ["serde_cbor"]
|
netplay = ["serde_cbor"]
|
||||||
editor = []
|
editor = []
|
||||||
exe = []
|
exe = []
|
||||||
|
@ -62,6 +63,7 @@ case_insensitive_hashmap = "1.0.0"
|
||||||
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
|
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
|
||||||
cpal = { git = "https://github.com/doukutsu-rs/cpal", rev = "9d269d8724102404e73a61e9def0c0cbc921b676" }
|
cpal = { git = "https://github.com/doukutsu-rs/cpal", rev = "9d269d8724102404e73a61e9def0c0cbc921b676" }
|
||||||
directories = "3"
|
directories = "3"
|
||||||
|
discord-rich-presence = "0.2"
|
||||||
downcast = "0.11"
|
downcast = "0.11"
|
||||||
glutin = { git = "https://github.com/doukutsu-rs/glutin.git", rev = "2dd95f042e6e090d36f577cbea125560dd99bd27", optional = true, default_features = false, features = ["x11"] }
|
glutin = { git = "https://github.com/doukutsu-rs/glutin.git", rev = "2dd95f042e6e090d36f577cbea125560dd99bd27", optional = true, default_features = false, features = ["x11"] }
|
||||||
imgui = "0.8"
|
imgui = "0.8"
|
||||||
|
|
|
@ -126,7 +126,8 @@
|
||||||
"entry": "Cutscene Skip:",
|
"entry": "Cutscene Skip:",
|
||||||
"hold": "Hold to Skip",
|
"hold": "Hold to Skip",
|
||||||
"fastforward": "Fast-Forward"
|
"fastforward": "Fast-Forward"
|
||||||
}
|
},
|
||||||
|
"discord_rpc": "Discord Rich Presence:"
|
||||||
},
|
},
|
||||||
"links": "Links...",
|
"links": "Links...",
|
||||||
"advanced": "Advanced...",
|
"advanced": "Advanced...",
|
||||||
|
|
|
@ -126,7 +126,8 @@
|
||||||
"entry": "カットシーンをスキップ",
|
"entry": "カットシーンをスキップ",
|
||||||
"hold": "を押し続け",
|
"hold": "を押し続け",
|
||||||
"fastforward": "はやおくり"
|
"fastforward": "はやおくり"
|
||||||
}
|
},
|
||||||
|
"discord_rpc": "Discord Rich Presence:"
|
||||||
},
|
},
|
||||||
"links": "リンク",
|
"links": "リンク",
|
||||||
"advanced": "詳細設定",
|
"advanced": "詳細設定",
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
use discord_rich_presence::{
|
||||||
|
activity::{Activity, Assets, Button},
|
||||||
|
DiscordIpc, DiscordIpcClient,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::framework::error::{GameError, GameResult};
|
||||||
|
use crate::game::{player::Player, stage::StageData};
|
||||||
|
|
||||||
|
pub enum DiscordRPCState {
|
||||||
|
Initializing,
|
||||||
|
Idling,
|
||||||
|
InGame,
|
||||||
|
Jukebox,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DiscordRPC {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub ready: bool,
|
||||||
|
|
||||||
|
client: DiscordIpcClient,
|
||||||
|
state: DiscordRPCState,
|
||||||
|
life: u16,
|
||||||
|
max_life: u16,
|
||||||
|
stage_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DiscordRPC {
|
||||||
|
pub fn new(app_id: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: false,
|
||||||
|
ready: false,
|
||||||
|
|
||||||
|
client: DiscordIpcClient::new(app_id).unwrap(),
|
||||||
|
state: DiscordRPCState::Idling,
|
||||||
|
life: 0,
|
||||||
|
max_life: 0,
|
||||||
|
stage_name: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(&mut self) -> GameResult {
|
||||||
|
log::info!("Starting Discord RPC client...");
|
||||||
|
|
||||||
|
match self.client.connect() {
|
||||||
|
Ok(_) => {
|
||||||
|
self.ready = true;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => Err(GameError::DiscordRPCError(e.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self) -> GameResult {
|
||||||
|
if !self.enabled {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let (state, details) = match self.state {
|
||||||
|
DiscordRPCState::Initializing => ("Initializing...".to_owned(), "Just started playing".to_owned()),
|
||||||
|
DiscordRPCState::Idling => ("In the menus".to_owned(), "Idling".to_owned()),
|
||||||
|
DiscordRPCState::InGame => {
|
||||||
|
(format!("Currently in: {}", self.stage_name), format!("HP: {} / {}", self.life, self.max_life))
|
||||||
|
}
|
||||||
|
DiscordRPCState::Jukebox => ("In the menus".to_owned(), "Listening to the soundtrack".to_owned()),
|
||||||
|
};
|
||||||
|
|
||||||
|
log::debug!("Updating Discord RPC state: {} - {}", state, details);
|
||||||
|
|
||||||
|
let activity = Activity::new()
|
||||||
|
.state(state.as_str())
|
||||||
|
.details(details.as_str())
|
||||||
|
.assets(Assets::new().large_image("drs"))
|
||||||
|
.buttons(vec![Button::new("doukutsu-rs on GitHub", "https://github.com/doukutsu-rs/doukutsu-rs")]);
|
||||||
|
|
||||||
|
match self.client.set_activity(activity) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => Err(GameError::DiscordRPCError(e.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_stage(&mut self, stage: &StageData) -> GameResult {
|
||||||
|
self.stage_name = stage.name.clone();
|
||||||
|
self.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_hp(&mut self, player: &Player) -> GameResult {
|
||||||
|
self.life = player.life;
|
||||||
|
self.max_life = player.max_life;
|
||||||
|
self.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_initializing(&mut self) -> GameResult {
|
||||||
|
self.set_state(DiscordRPCState::Initializing)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_idling(&mut self) -> GameResult {
|
||||||
|
self.set_state(DiscordRPCState::Idling)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_in_game(&mut self) -> GameResult {
|
||||||
|
self.set_state(DiscordRPCState::InGame)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_in_jukebox(&mut self) -> GameResult {
|
||||||
|
self.set_state(DiscordRPCState::Jukebox)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_state(&mut self, state: DiscordRPCState) -> GameResult {
|
||||||
|
self.state = state;
|
||||||
|
self.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) -> GameResult {
|
||||||
|
let _ = self.client.clear_activity();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dispose(&mut self) {
|
||||||
|
let _ = self.client.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,8 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
use std::sync::{Arc, PoisonError};
|
|
||||||
use std::sync::mpsc::SendError;
|
use std::sync::mpsc::SendError;
|
||||||
|
use std::sync::{Arc, PoisonError};
|
||||||
|
|
||||||
/// An enum containing all kinds of game framework errors.
|
/// An enum containing all kinds of game framework errors.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -44,6 +44,8 @@ pub enum GameError {
|
||||||
InvalidValue(String),
|
InvalidValue(String),
|
||||||
/// Something went wrong while executing a debug command line command.
|
/// Something went wrong while executing a debug command line command.
|
||||||
CommandLineError(String),
|
CommandLineError(String),
|
||||||
|
/// Something went wrong while initializing or modifying Discord rich presence values.
|
||||||
|
DiscordRPCError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for GameError {
|
impl fmt::Display for GameError {
|
||||||
|
|
|
@ -237,6 +237,12 @@ pub fn init(options: LaunchOptions) -> GameResult {
|
||||||
|
|
||||||
game.state.get_mut().fs_container = Some(fs_container);
|
game.state.get_mut().fs_container = Some(fs_container);
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
if game.state.get_mut().settings.discord_rpc {
|
||||||
|
game.state.get_mut().discord_rpc.enabled = true;
|
||||||
|
game.state.get_mut().discord_rpc.start()?;
|
||||||
|
}
|
||||||
|
|
||||||
game.state.get_mut().next_scene = Some(Box::new(LoadingScene::new()));
|
game.state.get_mut().next_scene = Some(Box::new(LoadingScene::new()));
|
||||||
log::info!("Starting main loop...");
|
log::info!("Starting main loop...");
|
||||||
context.run(game.as_mut().get_mut())?;
|
context.run(game.as_mut().get_mut())?;
|
||||||
|
|
|
@ -923,6 +923,9 @@ impl Player {
|
||||||
let _ = npc_list.spawn(0x100, npc.clone());
|
let _ = npc_list.spawn(0x100, npc.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
let _ = state.discord_rpc.update_hp(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_teleport_counter(&mut self, state: &SharedGameState) {
|
pub fn update_teleport_counter(&mut self, state: &SharedGameState) {
|
||||||
|
|
|
@ -319,6 +319,9 @@ impl Player {
|
||||||
npc.cond.set_alive(false);
|
npc.cond.set_alive(false);
|
||||||
|
|
||||||
state.sound_manager.play_sfx(20);
|
state.sound_manager.play_sfx(20);
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
let _ = state.discord_rpc.update_hp(&self);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ use std::rc::Rc;
|
||||||
use num_traits::{clamp, FromPrimitive};
|
use num_traits::{clamp, FromPrimitive};
|
||||||
|
|
||||||
use crate::bitfield;
|
use crate::bitfield;
|
||||||
use crate::common::{Direction, FadeDirection, FadeState, Rect};
|
|
||||||
use crate::common::Direction::{Left, Right};
|
use crate::common::Direction::{Left, Right};
|
||||||
|
use crate::common::{Direction, FadeDirection, FadeState, Rect};
|
||||||
use crate::engine_constants::EngineConstants;
|
use crate::engine_constants::EngineConstants;
|
||||||
use crate::entity::GameEntity;
|
use crate::entity::GameEntity;
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
|
@ -1032,6 +1032,9 @@ impl TextScriptVM {
|
||||||
game_scene.player2.life += life;
|
game_scene.player2.life += life;
|
||||||
game_scene.player2.max_life += life;
|
game_scene.player2.max_life += life;
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
state.discord_rpc.update_hp(&game_scene.player1)?;
|
||||||
|
|
||||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||||
}
|
}
|
||||||
TSCOpCode::FAC => {
|
TSCOpCode::FAC => {
|
||||||
|
@ -1534,6 +1537,9 @@ impl TextScriptVM {
|
||||||
game_scene.player1.life = clamp(game_scene.player1.life + life, 0, game_scene.player1.max_life);
|
game_scene.player1.life = clamp(game_scene.player1.life + life, 0, game_scene.player1.max_life);
|
||||||
game_scene.player2.life = clamp(game_scene.player2.life + life, 0, game_scene.player2.max_life);
|
game_scene.player2.life = clamp(game_scene.player2.life + life, 0, game_scene.player2.max_life);
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
state.discord_rpc.update_hp(&game_scene.player1)?;
|
||||||
|
|
||||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||||
}
|
}
|
||||||
TSCOpCode::ITp => {
|
TSCOpCode::ITp => {
|
||||||
|
|
|
@ -81,6 +81,8 @@ pub struct Settings {
|
||||||
pub more_rust: bool,
|
pub more_rust: bool,
|
||||||
#[serde(default = "default_cutscene_skip_mode")]
|
#[serde(default = "default_cutscene_skip_mode")]
|
||||||
pub cutscene_skip_mode: CutsceneSkipMode,
|
pub cutscene_skip_mode: CutsceneSkipMode,
|
||||||
|
#[serde(default = "default_true")]
|
||||||
|
pub discord_rpc: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_true() -> bool {
|
fn default_true() -> bool {
|
||||||
|
@ -89,7 +91,7 @@ fn default_true() -> bool {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn current_version() -> u32 {
|
fn current_version() -> u32 {
|
||||||
21
|
22
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -327,6 +329,11 @@ impl Settings {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.version == 21 {
|
||||||
|
self.version = 22;
|
||||||
|
self.discord_rpc = true;
|
||||||
|
}
|
||||||
|
|
||||||
if self.version != initial_version {
|
if self.version != initial_version {
|
||||||
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
||||||
}
|
}
|
||||||
|
@ -432,6 +439,7 @@ impl Default for Settings {
|
||||||
noclip: false,
|
noclip: false,
|
||||||
more_rust: false,
|
more_rust: false,
|
||||||
cutscene_skip_mode: CutsceneSkipMode::Hold,
|
cutscene_skip_mode: CutsceneSkipMode::Hold,
|
||||||
|
discord_rpc: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ use chrono::{Datelike, Local};
|
||||||
use crate::common::{ControlFlags, Direction, FadeState};
|
use crate::common::{ControlFlags, Direction, FadeState};
|
||||||
use crate::components::draw_common::{draw_number, Alignment};
|
use crate::components::draw_common::{draw_number, Alignment};
|
||||||
use crate::data::vanilla::VanillaExtractor;
|
use crate::data::vanilla::VanillaExtractor;
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
use crate::discord::DiscordRPC;
|
||||||
use crate::engine_constants::EngineConstants;
|
use crate::engine_constants::EngineConstants;
|
||||||
use crate::framework::backend::BackendTexture;
|
use crate::framework::backend::BackendTexture;
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
|
@ -334,6 +336,8 @@ pub struct SharedGameState {
|
||||||
pub loc: Locale,
|
pub loc: Locale,
|
||||||
pub tutorial_counter: u16,
|
pub tutorial_counter: u16,
|
||||||
pub more_rust: bool,
|
pub more_rust: bool,
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
pub discord_rpc: DiscordRPC,
|
||||||
pub shutdown: bool,
|
pub shutdown: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,6 +438,11 @@ impl SharedGameState {
|
||||||
let more_rust = (current_time.month() == 7 && current_time.day() == 7) || settings.more_rust;
|
let more_rust = (current_time.month() == 7 && current_time.day() == 7) || settings.more_rust;
|
||||||
let seed = chrono::Local::now().timestamp() as i32;
|
let seed = chrono::Local::now().timestamp() as i32;
|
||||||
|
|
||||||
|
let discord_rpc_app_id = match option_env!("DISCORD_RPC_APP_ID") {
|
||||||
|
Some(app_id) => app_id,
|
||||||
|
None => "1076523467337367622",
|
||||||
|
};
|
||||||
|
|
||||||
Ok(SharedGameState {
|
Ok(SharedGameState {
|
||||||
control_flags: ControlFlags(0),
|
control_flags: ControlFlags(0),
|
||||||
game_flags: BitVec::with_size(8000),
|
game_flags: BitVec::with_size(8000),
|
||||||
|
@ -489,6 +498,8 @@ impl SharedGameState {
|
||||||
loc: locale,
|
loc: locale,
|
||||||
tutorial_counter: 0,
|
tutorial_counter: 0,
|
||||||
more_rust,
|
more_rust,
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
discord_rpc: DiscordRPC::new(discord_rpc_app_id),
|
||||||
shutdown: false,
|
shutdown: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -709,6 +720,9 @@ impl SharedGameState {
|
||||||
|
|
||||||
pub fn shutdown(&mut self) {
|
pub fn shutdown(&mut self) {
|
||||||
self.shutdown = true;
|
self.shutdown = true;
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
self.discord_rpc.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stops SFX 40/41/58 (CPS and CSS)
|
// Stops SFX 40/41/58 (CPS and CSS)
|
||||||
|
|
|
@ -9,6 +9,8 @@ extern crate strum_macros;
|
||||||
mod common;
|
mod common;
|
||||||
mod components;
|
mod components;
|
||||||
mod data;
|
mod data;
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
pub mod discord;
|
||||||
#[cfg(feature = "editor")]
|
#[cfg(feature = "editor")]
|
||||||
mod editor;
|
mod editor;
|
||||||
mod engine_constants;
|
mod engine_constants;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
|
||||||
use crate::framework::error::{GameError::CommandLineError, GameResult};
|
use crate::framework::error::{GameError::CommandLineError, GameResult};
|
||||||
use crate::game::shared_game_state::SharedGameState;
|
|
||||||
use crate::game::npc::NPC;
|
use crate::game::npc::NPC;
|
||||||
use crate::scene::game_scene::GameScene;
|
|
||||||
use crate::game::scripting::tsc::text_script::{ScriptMode, TextScript, TextScriptEncoding};
|
use crate::game::scripting::tsc::text_script::{ScriptMode, TextScript, TextScriptEncoding};
|
||||||
|
use crate::game::shared_game_state::SharedGameState;
|
||||||
use crate::game::weapon::WeaponType;
|
use crate::game::weapon::WeaponType;
|
||||||
|
use crate::scene::game_scene::GameScene;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum CommandLineCommand {
|
pub enum CommandLineCommand {
|
||||||
|
@ -230,6 +230,9 @@ impl CommandLineCommand {
|
||||||
CommandLineCommand::SetMaxHP(hp_count) => {
|
CommandLineCommand::SetMaxHP(hp_count) => {
|
||||||
game_scene.player1.max_life = hp_count;
|
game_scene.player1.max_life = hp_count;
|
||||||
game_scene.player1.life = hp_count;
|
game_scene.player1.life = hp_count;
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
state.discord_rpc.update_hp(&game_scene.player1)?;
|
||||||
}
|
}
|
||||||
CommandLineCommand::SpawnNPC(id) => {
|
CommandLineCommand::SpawnNPC(id) => {
|
||||||
let mut npc = NPC::create(id, &state.npc_table);
|
let mut npc = NPC::create(id, &state.npc_table);
|
||||||
|
|
|
@ -268,6 +268,9 @@ impl LiveDebugger {
|
||||||
|
|
||||||
if scene.player1.life == 0 {
|
if scene.player1.life == 0 {
|
||||||
scene.player1.life = scene.player1.max_life;
|
scene.player1.life = scene.player1.max_life;
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
let _ = state.discord_rpc.update_hp(&scene.player1);
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.player2 = game_scene.player2.clone();
|
scene.player2 = game_scene.player2.clone();
|
||||||
|
|
|
@ -114,6 +114,8 @@ enum BehaviorMenuEntry {
|
||||||
GameTiming,
|
GameTiming,
|
||||||
PauseOnFocusLoss,
|
PauseOnFocusLoss,
|
||||||
CutsceneSkipMode,
|
CutsceneSkipMode,
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
DiscordRPC,
|
||||||
Back,
|
Back,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,6 +502,15 @@ impl SettingsMenu {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
self.behavior.push_entry(
|
||||||
|
BehaviorMenuEntry::DiscordRPC,
|
||||||
|
MenuEntry::Toggle(
|
||||||
|
state.loc.t("menus.options_menu.behavior_menu.discord_rpc").to_owned(),
|
||||||
|
state.settings.discord_rpc,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
self.behavior.push_entry(BehaviorMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
self.behavior.push_entry(BehaviorMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
||||||
|
|
||||||
self.links.push_entry(LinksMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
self.links.push_entry(LinksMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
||||||
|
@ -899,6 +910,26 @@ impl SettingsMenu {
|
||||||
let _ = state.settings.save(ctx);
|
let _ = state.settings.save(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
MenuSelectionResult::Selected(BehaviorMenuEntry::DiscordRPC, toggle) => {
|
||||||
|
if let MenuEntry::Toggle(_, value) = toggle {
|
||||||
|
state.settings.discord_rpc = !state.settings.discord_rpc;
|
||||||
|
let _ = state.settings.save(ctx);
|
||||||
|
|
||||||
|
*value = state.settings.discord_rpc;
|
||||||
|
state.discord_rpc.enabled = state.settings.discord_rpc;
|
||||||
|
|
||||||
|
if state.discord_rpc.enabled {
|
||||||
|
if !state.discord_rpc.ready {
|
||||||
|
state.discord_rpc.start()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.discord_rpc.set_idling()?;
|
||||||
|
} else {
|
||||||
|
state.discord_rpc.clear()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
MenuSelectionResult::Selected(BehaviorMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
MenuSelectionResult::Selected(BehaviorMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
||||||
self.current = CurrentMenu::MainMenu;
|
self.current = CurrentMenu::MainMenu;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1739,6 +1739,17 @@ impl Scene for GameScene {
|
||||||
self.pause_menu.init(state, ctx)?;
|
self.pause_menu.init(state, ctx)?;
|
||||||
self.whimsical_star.init(&self.player1);
|
self.whimsical_star.init(&self.player1);
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
{
|
||||||
|
if self.stage.data.map == state.stages[state.constants.game.intro_stage as usize].map {
|
||||||
|
state.discord_rpc.set_initializing()?;
|
||||||
|
} else {
|
||||||
|
state.discord_rpc.update_hp(&self.player1)?;
|
||||||
|
state.discord_rpc.update_stage(&self.stage.data)?;
|
||||||
|
state.discord_rpc.set_in_game()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,9 @@ impl Scene for JukeboxScene {
|
||||||
self.previous_pause_on_focus_loss_setting = state.settings.pause_on_focus_loss;
|
self.previous_pause_on_focus_loss_setting = state.settings.pause_on_focus_loss;
|
||||||
state.settings.pause_on_focus_loss = false;
|
state.settings.pause_on_focus_loss = false;
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
state.discord_rpc.set_in_jukebox()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -277,6 +277,9 @@ impl Scene for TitleScene {
|
||||||
state.replay_state = ReplayState::None;
|
state.replay_state = ReplayState::None;
|
||||||
state.textscript_vm.flags.set_cutscene_skip(false);
|
state.textscript_vm.flags.set_cutscene_skip(false);
|
||||||
|
|
||||||
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
state.discord_rpc.set_idling()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue