/// <summary> /// Handles when the user holds Control, Shift and Alt, and presses R /// </summary> private void HandleKeyPressCtrlS() { // Check for modifier keys if (!(KeyboardManager.CurrentState.IsKeyDown(Keys.LeftControl) || KeyboardManager.CurrentState.IsKeyDown(Keys.RightControl))) { return; } if (!KeyboardManager.IsUniqueKeyPress(Keys.S)) { return; } // Handle skin reloading switch (CurrentScreen.Type) { case QuaverScreenType.Menu: case QuaverScreenType.Select: case QuaverScreenType.Edit: Transitioner.FadeIn(); SkinManager.TimeSkinReloadRequested = GameBase.Game.TimeRunning; break; } }
/// <summary> /// Updates the screen manager /// </summary> /// <param name="gameTime"></param> public static void Update(GameTime gameTime) { var game = GameBase.Game as QuaverGame; if (QueuedScreen == game?.CurrentScreen || QueuedScreen == null) { return; } // Handle delayed screen changes. if (DelayedScreenChangeTime != 0) { TimeElapsedSinceDelayStarted += GameBase.Game.TimeSinceLastFrame; if (!(TimeElapsedSinceDelayStarted >= DelayedScreenChangeTime)) { return; } Transitioner.FadeIn(); TimeElapsedSinceDelayStarted = 0; DelayedScreenChangeTime = 0; return; } // Wait for fades to complete first. if (Transitioner.Blackness.Animations.Count != 0) { return; } var oldScreen = game.CurrentScreen; switch (ChangeType) { case QuaverScreenChangeType.CompleteChange: ChangeScreen(QueuedScreen); break; case QuaverScreenChangeType.AddToStack: AddScreen(QueuedScreen); break; case QuaverScreenChangeType.RemoveTopScreen: RemoveTopScreen(); Button.IsGloballyClickable = true; var screen = (QuaverScreen)ScreenManager.Screens.Peek(); screen.Exiting = false; break; default: throw new ArgumentOutOfRangeException(); } Transitioner.FadeOut(); }
/// <summary> /// Creates the button to save changes /// </summary> private void CreateOkButton() { OkButton = new BorderedTextButton("OK", Color.LimeGreen) { Parent = FooterContainer, Alignment = Alignment.MidRight, X = -20 }; OkButton.Clicked += (o, e) => { // Determines whether we'll be dismissing the dialog if no changes have been made. var dismissDalog = true; // Handle skin reloads if (SkinManager.NewQueuedSkin != null || NewQueuedDefaultSkin != ConfigManager.DefaultSkin.Value) { ConfigManager.Skin.Value = SkinManager.NewQueuedSkin; ConfigManager.DefaultSkin.Value = NewQueuedDefaultSkin; Transitioner.FadeIn(); SkinManager.TimeSkinReloadRequested = GameBase.Game.TimeRunning; // IsGloballyClickable = false; dismissDalog = false; } // Handle screen resolution changes. if (NewQueuedScreenResolution.X != ConfigManager.WindowWidth.Value && NewQueuedScreenResolution.Y != ConfigManager.WindowHeight.Value) { ConfigManager.WindowWidth.Value = NewQueuedScreenResolution.X; ConfigManager.WindowHeight.Value = NewQueuedScreenResolution.Y; WindowManager.ChangeScreenResolution(NewQueuedScreenResolution); dismissDalog = false; } if (dismissDalog) { DialogManager.Dismiss(this); } }; }
/// <summary> /// Updates the screen manager /// </summary> /// <param name="gameTime"></param> public static void Update(GameTime gameTime) { var game = GameBase.Game as QuaverGame; if (QueuedScreen == game?.CurrentScreen || QueuedScreen == null) { return; } // Handle delayed screen changes. if (DelayedScreenChangeTime != 0) { TimeElapsedSinceDelayStarted += GameBase.Game.TimeSinceLastFrame; if (!(TimeElapsedSinceDelayStarted >= DelayedScreenChangeTime)) { return; } Transitioner.FadeIn(); TimeElapsedSinceDelayStarted = 0; DelayedScreenChangeTime = 0; return; } // Wait for fades to complete first. if (Transitioner.Blackness.Animations.Count != 0) { return; } var oldScreen = game.CurrentScreen; ChangeScreen(QueuedScreen); oldScreen = null; Transitioner.FadeOut(); }
/// <summary> /// Schedules the current screen to start changing to the next /// </summary> /// <param name="newScreen"></param> /// <param name="delayFade"></param> public static void ScheduleScreenChange(Func <QuaverScreen> newScreen, bool delayFade = false) { if (!delayFade) { Transitioner.FadeIn(); } ThreadScheduler.Run(() => { if (QueuedScreen != null) { lock (QueuedScreen) QueuedScreen = newScreen(); } else { QueuedScreen = newScreen(); } Logger.Important($"Scheduled screen change to: '{QueuedScreen.Type}'. w/ {DelayedScreenChangeTime}ms delay", LogType.Runtime); }); }
/// <summary> /// Imports a skin file. /// </summary> public static void Import(string path) { Transitioner.FadeIn(); try { ThreadScheduler.Run(() => { var skinName = Path.GetFileNameWithoutExtension(path); var dir = $"{ConfigManager.SkinDirectory.Value}/{skinName}"; Directory.CreateDirectory(dir); // Extract the skin into a directory. using (var archive = ArchiveFactory.Open(path)) { foreach (var entry in archive.Entries) { if (!entry.IsDirectory) { entry.WriteToDirectory(dir, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true }); } } } // Reload the skin. ConfigManager.Skin.Value = skinName; NewQueuedSkin = skinName; TimeSkinReloadRequested = GameBase.Game.TimeRunning; }); } catch (Exception e) { Logger.Error(e, LogType.Runtime); } }
/// <summary> /// Creates a new mapset with an audio file. /// </summary> /// <param name="audioFile"></param> public static void HandleNewMapsetCreation(string audioFile) { try { var game = GameBase.Game as QuaverGame; // Add a fade effect and make butotns not clickable // so the user can't perform any actions during this time. Transitioner.FadeIn(); Button.IsGloballyClickable = false; var tagFile = TagLib.File.Create(audioFile); // Create a fresh .qua with the available metadata from the file var qua = new Qua() { AudioFile = Path.GetFileName(audioFile), Artist = tagFile.Tag.FirstPerformer ?? "", Title = tagFile.Tag.Title ?? "", Source = tagFile.Tag.Album ?? "", Tags = string.Join(" ", tagFile.Tag.Genres) ?? "", Creator = ConfigManager.Username.Value, DifficultyName = "", // Makes the file different to prevent exception thrown in the DB for same md5 checksum Description = $"Created at {TimeHelper.GetUnixTimestampMilliseconds()}", BackgroundFile = "", Mode = GameMode.Keys4 }; // Create a new directory to house the map. var dir = $"{ConfigManager.SongDirectory.Value}/{TimeHelper.GetUnixTimestampMilliseconds()}"; Directory.CreateDirectory(dir); // Copy over the audio file into the directory File.Copy(audioFile, $"{dir}/{Path.GetFileName(audioFile)}"); // Save the new .qua file into the directory var path = $"{dir}/{StringHelper.FileNameSafeString($"{qua.Artist} - {qua.Title} [{qua.DifficultyName}] - {TimeHelper.GetUnixTimestampMilliseconds()}")}.qua"; qua.Save(path); // Place the new map inside of the database and make sure all the loaded maps are correct var map = Map.FromQua(qua, path); map.Id = MapDatabaseCache.InsertMap(map, path); MapDatabaseCache.OrderAndSetMapsets(); MapManager.Selected.Value = map; MapManager.Selected.Value.Qua = qua; var selectedMapset = MapManager.Mapsets.Find(x => x.Maps.Any(y => y.Id == MapManager.Selected.Value.Id)); // Find the new object from the loaded maps that contains the same id. MapManager.Selected.Value = selectedMapset.Maps.Find(x => x.Id == MapManager.Selected.Value.Id); MapManager.Selected.Value.Qua = qua; MapManager.Selected.Value.NewlyCreated = true; game?.CurrentScreen.Exit(() => new EditorScreen(qua)); } catch (Exception e) { Logger.Error(e, LogType.Runtime); var game = GameBase.Game as QuaverGame; game?.CurrentScreen.Exit(() => { NotificationManager.Show(NotificationLevel.Error, "Could not create new mapset with that audio file."); return(new SelectScreen()); }); } }
/// <summary> /// Creates the button to save changes /// </summary> private void CreateApplyButton() { ApplyButton = new BorderedTextButton("Apply", Color.LimeGreen) { Parent = FooterContainer, Alignment = Alignment.MidRight, X = -20 }; ApplyButton.Clicked += (o, e) => { // Determines whether we'll be dismissing the dialog if no changes have been made. var dismissDalog = true; // Handle skin reloads if (SkinManager.NewQueuedSkin != null && SkinManager.NewQueuedSkin != ConfigManager.Skin.Value || NewQueuedDefaultSkin != ConfigManager.DefaultSkin.Value) { ConfigManager.Skin.Value = SkinManager.NewQueuedSkin; ConfigManager.DefaultSkin.Value = NewQueuedDefaultSkin; Transitioner.FadeIn(); SkinManager.TimeSkinReloadRequested = GameBase.Game.TimeRunning; dismissDalog = false; } // Handle screen resolution changes. if (NewQueuedScreenResolution.X != ConfigManager.WindowWidth.Value && NewQueuedScreenResolution.Y != ConfigManager.WindowHeight.Value) { ConfigManager.WindowWidth.Value = NewQueuedScreenResolution.X; ConfigManager.WindowHeight.Value = NewQueuedScreenResolution.Y; WindowManager.ChangeScreenResolution(NewQueuedScreenResolution); dismissDalog = false; } // Handle device period and buffer length changes. if (Environment.OSVersion.Platform == PlatformID.Unix) { if (ConfigManager.DevicePeriod.Value != Bass.GetConfig(Configuration.DevicePeriod) || ConfigManager.DeviceBufferLengthMultiplier.Value != Bass.GetConfig(Configuration.DeviceBufferLength) / Bass.GetConfig(Configuration.DevicePeriod)) { DialogManager.Show(new ConfirmCancelDialog( "The game must be restarted to apply the new audio device properties. Exit the game now?", (sender, args) => { // Make sure the config is saved. Task.Run(ConfigManager.WriteConfigFileAsync).Wait(); var game = GameBase.Game as QuaverGame; game?.Exit(); })); } } if (dismissDalog) { DialogManager.Dismiss(this); } }; }
/// <summary> /// Exits the screen to schedule loading the map and ultimately the gameplay screen /// </summary> public void ExitToGameplay() { IsExitingToGameplay = true; if (OnlineManager.CurrentGame != null) { var map = MapManager.Selected.Value; var diff = map.DifficultyFromMods(ModManager.Mods); // Prevent host from picking a map not within difficulty range if (diff < OnlineManager.CurrentGame.MinimumDifficultyRating || diff > OnlineManager.CurrentGame.MaximumDifficultyRating) { NotificationManager.Show(NotificationLevel.Error, $"Difficulty rating must be between " + $"{OnlineManager.CurrentGame.MinimumDifficultyRating} and {OnlineManager.CurrentGame.MaximumDifficultyRating} " + $"for this multiplayer match!"); return; } // Pevent host from picking a map not in max song length range if (map.SongLength * ModHelper.GetRateFromMods(ModManager.Mods) / 1000 > OnlineManager.CurrentGame.MaximumSongLength) { NotificationManager.Show(NotificationLevel.Error, $"The maximum length allowed for this multiplayer match is: " + $"{OnlineManager.CurrentGame.MaximumSongLength} seconds"); return; } // Prevent disallowed game modes from being selected if (!OnlineManager.CurrentGame.AllowedGameModes.Contains((byte)map.Mode)) { NotificationManager.Show(NotificationLevel.Error, "You cannot pick maps of this game mode in this multiplayer match!"); return; } // Prevent maps not in range of the minimum and maximum LN% if (map.LNPercentage < OnlineManager.CurrentGame.MinimumLongNotePercentage || map.LNPercentage > OnlineManager.CurrentGame.MaximumLongNotePercentage) { NotificationManager.Show(NotificationLevel.Error, $"You cannot select this map. The long note percentage must be between " + $"{OnlineManager.CurrentGame.MinimumLongNotePercentage}%-{OnlineManager.CurrentGame.MaximumLongNotePercentage}% " + $"for this multiplayer match."); return; } // Start the fade out early to make it look like the screen is loading Transitioner.FadeIn(); ThreadScheduler.Run(() => { OnlineManager.Client.ChangeMultiplayerGameMap(map.Md5Checksum, map.MapId, map.MapSetId, map.ToString(), (byte)map.Mode, map.DifficultyFromMods(ModManager.Mods), map.GetDifficultyRatings(), map.GetJudgementCount(), MapManager.Selected.Value.GetAlternativeMd5()); OnlineManager.Client.SetGameCurrentlySelectingMap(false); RemoveTopScreen(MultiplayerScreen); }); return; } Exit(() => { var game = GameBase.Game as QuaverGame; var cursor = game.GlobalUserInterface.Cursor; cursor.Animations.Add(new Animation(AnimationProperty.Alpha, Easing.Linear, cursor.Alpha, 0, 200)); if (AudioEngine.Track != null) { lock (AudioEngine.Track) AudioEngine.Track?.Fade(10, 500); } return(new MapLoadingScreen(new List <Score>())); }, 100); }