mirror of
https://github.com/osukey/osukey.git
synced 2025-08-02 14:17:06 +09:00
Merge branch 'master' of https://github.com/ppy/osu into present-recommended
Conflicts: osu.Game/OsuGameBase.cs osu.Game/Screens/Select/DifficultyRecommender.cs osu.Game/Screens/Select/SongSelect.cs
This commit is contained in:
@ -18,6 +18,7 @@ using osu.Game.Screens.Menu;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Humanizer;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
@ -30,23 +31,27 @@ using osu.Framework.Input.Events;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Collections;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Input;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Overlays.Music;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK.Graphics;
|
||||
using osu.Game.Overlays.Volume;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Updater;
|
||||
using osu.Game.Utils;
|
||||
using LogLevel = osu.Framework.Logging.LogLevel;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game
|
||||
{
|
||||
@ -62,14 +67,15 @@ namespace osu.Game
|
||||
|
||||
private ChannelManager channelManager;
|
||||
|
||||
private NotificationOverlay notifications;
|
||||
|
||||
private NowPlayingOverlay nowPlaying;
|
||||
[NotNull]
|
||||
private readonly NotificationOverlay notifications = new NotificationOverlay();
|
||||
|
||||
private BeatmapListingOverlay beatmapListing;
|
||||
|
||||
private DashboardOverlay dashboard;
|
||||
|
||||
private NewsOverlay news;
|
||||
|
||||
private UserProfileOverlay userProfile;
|
||||
|
||||
private BeatmapSetOverlay beatmapSetOverlay;
|
||||
@ -81,11 +87,23 @@ namespace osu.Game
|
||||
|
||||
public virtual Storage GetStorageForStableInstall() => null;
|
||||
|
||||
public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight;
|
||||
public float ToolbarOffset => (Toolbar?.Position.Y ?? 0) + (Toolbar?.DrawHeight ?? 0);
|
||||
|
||||
private IdleTracker idleTracker;
|
||||
|
||||
public readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
|
||||
/// <summary>
|
||||
/// Whether overlays should be able to be opened game-wide. Value is sourced from the current active screen.
|
||||
/// </summary>
|
||||
public readonly IBindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the local user is currently interacting with the game in a way that should not be interrupted.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is exclusively managed by <see cref="Player"/>. If other components are mutating this state, a more
|
||||
/// resilient method should be used to ensure correct state.
|
||||
/// </remarks>
|
||||
public Bindable<bool> LocalUserPlaying = new BindableBool();
|
||||
|
||||
protected OsuScreenStack ScreenStack;
|
||||
|
||||
@ -164,7 +182,7 @@ namespace osu.Game
|
||||
|
||||
if (args?.Length > 0)
|
||||
{
|
||||
var paths = args.Where(a => !a.StartsWith(@"-")).ToArray();
|
||||
var paths = args.Where(a => !a.StartsWith('-')).ToArray();
|
||||
if (paths.Length > 0)
|
||||
Task.Run(() => Import(paths));
|
||||
}
|
||||
@ -249,7 +267,7 @@ namespace osu.Game
|
||||
case LinkAction.OpenEditorTimestamp:
|
||||
case LinkAction.JoinMultiplayerMatch:
|
||||
case LinkAction.Spectate:
|
||||
waitForReady(() => notifications, _ => notifications?.Post(new SimpleNotification
|
||||
waitForReady(() => notifications, _ => notifications.Post(new SimpleNotification
|
||||
{
|
||||
Text = @"This link type is not yet supported!",
|
||||
Icon = FontAwesome.Solid.LifeRing,
|
||||
@ -261,7 +279,7 @@ namespace osu.Game
|
||||
break;
|
||||
|
||||
case LinkAction.OpenUserProfile:
|
||||
if (long.TryParse(link.Argument, out long userId))
|
||||
if (int.TryParse(link.Argument, out int userId))
|
||||
ShowUser(userId);
|
||||
break;
|
||||
|
||||
@ -272,7 +290,7 @@ namespace osu.Game
|
||||
|
||||
public void OpenUrlExternally(string url) => waitForReady(() => externalLinkOpener, _ =>
|
||||
{
|
||||
if (url.StartsWith("/"))
|
||||
if (url.StartsWith('/'))
|
||||
url = $"{API.Endpoint}{url}";
|
||||
|
||||
externalLinkOpener.OpenUrlExternally(url);
|
||||
@ -304,7 +322,7 @@ namespace osu.Game
|
||||
/// Show a user's profile as an overlay.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user to display.</param>
|
||||
public void ShowUser(long userId) => waitForReady(() => userProfile, _ => userProfile.ShowUser(userId));
|
||||
public void ShowUser(int userId) => waitForReady(() => userProfile, _ => userProfile.ShowUser(userId));
|
||||
|
||||
/// <summary>
|
||||
/// Show a beatmap's set as an overlay, displaying the given beatmap.
|
||||
@ -370,7 +388,7 @@ namespace osu.Game
|
||||
/// Present a score's replay immediately.
|
||||
/// The user should have already requested this interactively.
|
||||
/// </summary>
|
||||
public void PresentScore(ScoreInfo score)
|
||||
public void PresentScore(ScoreInfo score, ScorePresentType presentType = ScorePresentType.Results)
|
||||
{
|
||||
// The given ScoreInfo may have missing properties if it was retrieved from online data. Re-retrieve it from the database
|
||||
// to ensure all the required data for presenting a replay are present.
|
||||
@ -402,9 +420,19 @@ namespace osu.Game
|
||||
|
||||
PerformFromScreen(screen =>
|
||||
{
|
||||
Ruleset.Value = databasedScore.ScoreInfo.Ruleset;
|
||||
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap);
|
||||
|
||||
screen.Push(new ReplayPlayerLoader(databasedScore));
|
||||
switch (presentType)
|
||||
{
|
||||
case ScorePresentType.Gameplay:
|
||||
screen.Push(new ReplayPlayerLoader(databasedScore));
|
||||
break;
|
||||
|
||||
case ScorePresentType.Results:
|
||||
screen.Push(new SoloResultsScreen(databasedScore.ScoreInfo));
|
||||
break;
|
||||
}
|
||||
}, validScreens: new[] { typeof(PlaySongSelect) });
|
||||
}
|
||||
|
||||
@ -422,23 +450,7 @@ namespace osu.Game
|
||||
|
||||
updateModDefaults();
|
||||
|
||||
var newBeatmap = beatmap.NewValue;
|
||||
|
||||
if (newBeatmap != null)
|
||||
{
|
||||
newBeatmap.Track.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap));
|
||||
newBeatmap.BeginAsyncLoad();
|
||||
}
|
||||
|
||||
void trackCompleted(WorkingBeatmap b)
|
||||
{
|
||||
// the source of track completion is the audio thread, so the beatmap may have changed before firing.
|
||||
if (Beatmap.Value != b)
|
||||
return;
|
||||
|
||||
if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled)
|
||||
MusicController.NextTrack();
|
||||
}
|
||||
beatmap.NewValue?.BeginAsyncLoad();
|
||||
}
|
||||
|
||||
private void modsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
||||
@ -461,7 +473,7 @@ namespace osu.Game
|
||||
|
||||
#endregion
|
||||
|
||||
private ScheduledDelegate performFromMainMenuTask;
|
||||
private PerformFromMenuRunner performFromMainMenuTask;
|
||||
|
||||
/// <summary>
|
||||
/// Perform an action only after returning to a specific screen as indicated by <paramref name="validScreens"/>.
|
||||
@ -472,34 +484,7 @@ namespace osu.Game
|
||||
public void PerformFromScreen(Action<IScreen> action, IEnumerable<Type> validScreens = null)
|
||||
{
|
||||
performFromMainMenuTask?.Cancel();
|
||||
|
||||
validScreens ??= Enumerable.Empty<Type>();
|
||||
validScreens = validScreens.Append(typeof(MainMenu));
|
||||
|
||||
CloseAllOverlays(false);
|
||||
|
||||
// we may already be at the target screen type.
|
||||
if (validScreens.Contains(ScreenStack.CurrentScreen?.GetType()) && !Beatmap.Disabled)
|
||||
{
|
||||
action(ScreenStack.CurrentScreen);
|
||||
return;
|
||||
}
|
||||
|
||||
// find closest valid target
|
||||
IScreen screen = ScreenStack.CurrentScreen;
|
||||
|
||||
while (screen != null)
|
||||
{
|
||||
if (validScreens.Contains(screen.GetType()))
|
||||
{
|
||||
screen.MakeCurrent();
|
||||
break;
|
||||
}
|
||||
|
||||
screen = screen.GetParentScreen();
|
||||
}
|
||||
|
||||
performFromMainMenuTask = Schedule(() => PerformFromScreen(action, validScreens));
|
||||
Add(performFromMainMenuTask = new PerformFromMenuRunner(action, validScreens, () => ScreenStack.CurrentScreen));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -535,17 +520,31 @@ namespace osu.Game
|
||||
MenuCursorContainer.CanShowCursor = menuScreen?.CursorVisible ?? false;
|
||||
|
||||
// todo: all archive managers should be able to be looped here.
|
||||
SkinManager.PostNotification = n => notifications?.Post(n);
|
||||
SkinManager.PostNotification = n => notifications.Post(n);
|
||||
SkinManager.GetStableStorage = GetStorageForStableInstall;
|
||||
|
||||
BeatmapManager.PostNotification = n => notifications?.Post(n);
|
||||
BeatmapManager.PostNotification = n => notifications.Post(n);
|
||||
BeatmapManager.GetStableStorage = GetStorageForStableInstall;
|
||||
BeatmapManager.PresentImport = items => PresentBeatmap(items.First());
|
||||
|
||||
ScoreManager.PostNotification = n => notifications?.Post(n);
|
||||
ScoreManager.PostNotification = n => notifications.Post(n);
|
||||
ScoreManager.GetStableStorage = GetStorageForStableInstall;
|
||||
ScoreManager.PresentImport = items => PresentScore(items.First());
|
||||
|
||||
// make config aware of how to lookup skins for on-screen display purposes.
|
||||
// if this becomes a more common thing, tracked settings should be reconsidered to allow local DI.
|
||||
LocalConfig.LookupSkinName = id => SkinManager.GetAllUsableSkins().FirstOrDefault(s => s.ID == id)?.ToString() ?? "Unknown";
|
||||
|
||||
LocalConfig.LookupKeyBindings = l =>
|
||||
{
|
||||
var combinations = KeyBindingStore.GetReadableKeyCombinationsFor(l).ToArray();
|
||||
|
||||
if (combinations.Length == 0)
|
||||
return "none";
|
||||
|
||||
return string.Join(" or ", combinations);
|
||||
};
|
||||
|
||||
Container logoContainer;
|
||||
BackButton.Receptor receptor;
|
||||
|
||||
@ -572,7 +571,9 @@ namespace osu.Game
|
||||
Origin = Anchor.BottomLeft,
|
||||
Action = () =>
|
||||
{
|
||||
if ((ScreenStack.CurrentScreen as IOsuScreen)?.AllowBackButton == true)
|
||||
var currentScreen = ScreenStack.CurrentScreen as IOsuScreen;
|
||||
|
||||
if (currentScreen?.AllowBackButton == true && !currentScreen.OnBackButton())
|
||||
ScreenStack.Exit();
|
||||
}
|
||||
},
|
||||
@ -583,7 +584,8 @@ namespace osu.Game
|
||||
rightFloatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both },
|
||||
leftFloatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both },
|
||||
topMostOverlayContent = new Container { RelativeSizeAxes = Axes.Both },
|
||||
idleTracker
|
||||
idleTracker,
|
||||
new ConfineMouseTracker()
|
||||
});
|
||||
|
||||
ScreenStack.ScreenPushed += screenPushed;
|
||||
@ -608,22 +610,36 @@ namespace osu.Game
|
||||
|
||||
loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add, true);
|
||||
|
||||
loadComponentSingleFile(new OnScreenDisplay(), Add, true);
|
||||
var onScreenDisplay = new OnScreenDisplay();
|
||||
|
||||
loadComponentSingleFile(MusicController = new MusicController(), Add, true);
|
||||
onScreenDisplay.BeginTracking(this, frameworkConfig);
|
||||
onScreenDisplay.BeginTracking(this, LocalConfig);
|
||||
|
||||
loadComponentSingleFile(notifications = new NotificationOverlay
|
||||
loadComponentSingleFile(onScreenDisplay, Add, true);
|
||||
|
||||
loadComponentSingleFile(notifications.With(d =>
|
||||
{
|
||||
GetToolbarHeight = () => ToolbarOffset,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
}, rightFloatingOverlayContent.Add, true);
|
||||
d.GetToolbarHeight = () => ToolbarOffset;
|
||||
d.Anchor = Anchor.TopRight;
|
||||
d.Origin = Anchor.TopRight;
|
||||
}), rightFloatingOverlayContent.Add, true);
|
||||
|
||||
loadComponentSingleFile(new CollectionManager(Storage)
|
||||
{
|
||||
PostNotification = n => notifications.Post(n),
|
||||
GetStableStorage = GetStorageForStableInstall
|
||||
}, Add, true);
|
||||
|
||||
loadComponentSingleFile(screenshotManager, Add);
|
||||
|
||||
// dependency on notification overlay, dependent by settings overlay
|
||||
loadComponentSingleFile(CreateUpdateManager(), Add, true);
|
||||
|
||||
// overlay elements
|
||||
loadComponentSingleFile(new ManageCollectionsDialog(), overlayContent.Add, true);
|
||||
loadComponentSingleFile(beatmapListing = new BeatmapListingOverlay(), overlayContent.Add, true);
|
||||
loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true);
|
||||
loadComponentSingleFile(news = new NewsOverlay(), overlayContent.Add, true);
|
||||
var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true);
|
||||
loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal, true);
|
||||
loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true);
|
||||
@ -639,7 +655,7 @@ namespace osu.Game
|
||||
Origin = Anchor.TopRight,
|
||||
}, rightFloatingOverlayContent.Add, true);
|
||||
|
||||
loadComponentSingleFile(nowPlaying = new NowPlayingOverlay
|
||||
loadComponentSingleFile(new NowPlayingOverlay
|
||||
{
|
||||
GetToolbarHeight = () => ToolbarOffset,
|
||||
Anchor = Anchor.TopRight,
|
||||
@ -648,12 +664,11 @@ namespace osu.Game
|
||||
|
||||
loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true);
|
||||
loadComponentSingleFile(new DialogOverlay(), topMostOverlayContent.Add, true);
|
||||
loadComponentSingleFile(externalLinkOpener = new ExternalLinkOpener(), topMostOverlayContent.Add);
|
||||
|
||||
chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
|
||||
|
||||
Add(externalLinkOpener = new ExternalLinkOpener());
|
||||
Add(CreateUpdateManager()); // dependency on notification overlay
|
||||
Add(new MusicKeyBindingHandler());
|
||||
|
||||
// side overlays which cancel each other.
|
||||
var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications };
|
||||
@ -675,14 +690,13 @@ namespace osu.Game
|
||||
{
|
||||
overlay.State.ValueChanged += state =>
|
||||
{
|
||||
if (state.NewValue == Visibility.Hidden) return;
|
||||
|
||||
informationalOverlays.Where(o => o != overlay).ForEach(o => o.Hide());
|
||||
if (state.NewValue != Visibility.Hidden)
|
||||
showOverlayAboveOthers(overlay, informationalOverlays);
|
||||
};
|
||||
}
|
||||
|
||||
// ensure only one of these overlays are open at once.
|
||||
var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, dashboard, beatmapListing, changelogOverlay, rankingsOverlay };
|
||||
var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, news, dashboard, beatmapListing, changelogOverlay, rankingsOverlay };
|
||||
|
||||
foreach (var overlay in singleDisplayOverlays)
|
||||
{
|
||||
@ -691,9 +705,8 @@ namespace osu.Game
|
||||
// informational overlays should be dismissed on a show or hide of a full overlay.
|
||||
informationalOverlays.ForEach(o => o.Hide());
|
||||
|
||||
if (state.NewValue == Visibility.Hidden) return;
|
||||
|
||||
singleDisplayOverlays.Where(o => o != overlay).ForEach(o => o.Hide());
|
||||
if (state.NewValue != Visibility.Hidden)
|
||||
showOverlayAboveOthers(overlay, singleDisplayOverlays);
|
||||
};
|
||||
}
|
||||
|
||||
@ -707,9 +720,9 @@ namespace osu.Game
|
||||
float offset = 0;
|
||||
|
||||
if (Settings.State.Value == Visibility.Visible)
|
||||
offset += ToolbarButton.WIDTH / 2;
|
||||
offset += Toolbar.HEIGHT / 2;
|
||||
if (notifications.State.Value == Visibility.Visible)
|
||||
offset -= ToolbarButton.WIDTH / 2;
|
||||
offset -= Toolbar.HEIGHT / 2;
|
||||
|
||||
screenContainer.MoveToX(offset, SettingsPanel.TRANSITION_LENGTH, Easing.OutQuint);
|
||||
}
|
||||
@ -718,22 +731,13 @@ namespace osu.Game
|
||||
notifications.State.ValueChanged += _ => updateScreenOffset();
|
||||
}
|
||||
|
||||
public class GameIdleTracker : IdleTracker
|
||||
private void showOverlayAboveOthers(OverlayContainer overlay, OverlayContainer[] otherOverlays)
|
||||
{
|
||||
private InputManager inputManager;
|
||||
otherOverlays.Where(o => o != overlay).ForEach(o => o.Hide());
|
||||
|
||||
public GameIdleTracker(int time)
|
||||
: base(time)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
inputManager = GetContainingInputManager();
|
||||
}
|
||||
|
||||
protected override bool AllowIdle => inputManager.FocusedDrawable == null;
|
||||
// show above others if not visible at all, else leave at current depth.
|
||||
if (!overlay.IsPresent)
|
||||
overlayContent.ChangeChildDepth(overlay, (float)-Clock.CurrentTime);
|
||||
}
|
||||
|
||||
private void forwardLoggedErrorsToNotifications()
|
||||
@ -753,7 +757,7 @@ namespace osu.Game
|
||||
Schedule(() => notifications.Post(new SimpleNotification
|
||||
{
|
||||
Icon = entry.Level == LogLevel.Important ? FontAwesome.Solid.ExclamationCircle : FontAwesome.Solid.Bomb,
|
||||
Text = entry.Message + (entry.Exception != null && IsDeployedBuild ? "\n\nThis error has been automatically reported to the devs." : string.Empty),
|
||||
Text = entry.Message.Truncate(256) + (entry.Exception != null && IsDeployedBuild ? "\n\nThis error has been automatically reported to the devs." : string.Empty),
|
||||
}));
|
||||
}
|
||||
else if (recentLogCount == short_term_display_limit)
|
||||
@ -764,7 +768,7 @@ namespace osu.Game
|
||||
Text = "Subsequent messages have been logged. Click to view log files.",
|
||||
Activated = () =>
|
||||
{
|
||||
Host.Storage.GetStorageForDirectory("logs").OpenInNativeExplorer();
|
||||
Storage.GetStorageForDirectory("logs").OpenInNativeExplorer();
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
@ -852,18 +856,6 @@ namespace osu.Game
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case GlobalAction.ToggleNowPlaying:
|
||||
nowPlaying.ToggleVisibility();
|
||||
return true;
|
||||
|
||||
case GlobalAction.ToggleChat:
|
||||
chatOverlay.ToggleVisibility();
|
||||
return true;
|
||||
|
||||
case GlobalAction.ToggleSocial:
|
||||
dashboard.ToggleVisibility();
|
||||
return true;
|
||||
|
||||
case GlobalAction.ResetInputSettings:
|
||||
var sensitivity = frameworkConfig.GetBindable<double>(FrameworkSetting.CursorSensitivity);
|
||||
|
||||
@ -879,17 +871,13 @@ namespace osu.Game
|
||||
Toolbar.ToggleVisibility();
|
||||
return true;
|
||||
|
||||
case GlobalAction.ToggleSettings:
|
||||
Settings.ToggleVisibility();
|
||||
return true;
|
||||
|
||||
case GlobalAction.ToggleDirect:
|
||||
beatmapListing.ToggleVisibility();
|
||||
return true;
|
||||
|
||||
case GlobalAction.ToggleGameplayMouseButtons:
|
||||
LocalConfig.Set(OsuSetting.MouseDisableButtons, !LocalConfig.Get<bool>(OsuSetting.MouseDisableButtons));
|
||||
return true;
|
||||
|
||||
case GlobalAction.RandomSkin:
|
||||
SkinManager.SelectRandomSkin();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -926,8 +914,6 @@ namespace osu.Game
|
||||
|
||||
private ScalingContainer screenContainer;
|
||||
|
||||
protected MusicController MusicController { get; private set; }
|
||||
|
||||
protected override bool OnExiting()
|
||||
{
|
||||
if (ScreenStack.CurrentScreen is Loader)
|
||||
@ -977,9 +963,19 @@ namespace osu.Game
|
||||
break;
|
||||
}
|
||||
|
||||
// reset on screen change for sanity.
|
||||
LocalUserPlaying.Value = false;
|
||||
|
||||
if (current is IOsuScreen currentOsuScreen)
|
||||
{
|
||||
OverlayActivationMode.UnbindFrom(currentOsuScreen.OverlayActivationMode);
|
||||
API.Activity.UnbindFrom(currentOsuScreen.Activity);
|
||||
}
|
||||
|
||||
if (newScreen is IOsuScreen newOsuScreen)
|
||||
{
|
||||
OverlayActivationMode.Value = newOsuScreen.InitialOverlayActivationMode;
|
||||
OverlayActivationMode.BindTo(newOsuScreen.OverlayActivationMode);
|
||||
((IBindable<UserActivity>)API.Activity).BindTo(newOsuScreen.Activity);
|
||||
|
||||
MusicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments;
|
||||
|
||||
|
Reference in New Issue
Block a user