Exemple #1
0
        /// <summary>
        ///     Skips the song to the next object if on a break.
        /// </summary>
        private void SkipToNextObject()
        {
            if (!EligibleToSkip || IsPaused || IsResumeInProgress)
            {
                return;
            }

            // Get the skip time of the next object.
            var nextObject = Ruleset.HitObjectManager.NextHitObject.StartTime;
            var skipTime   = nextObject - GameplayAudioTiming.StartDelay * ModHelper.GetRateFromMods(ModManager.Mods);

            try
            {
                // Skip to the time if the audio already played once. If it hasn't, then play it.
                AudioEngine.Track?.Seek(skipTime);
                Timing.Time = AudioEngine.Track.Time;
            }
            catch (Exception e)
            {
                Logger.Error(e, LogType.Runtime);
                Logger.Warning("Trying to skip with no audio file loaded. Still continuing..", LogType.Runtime);
                Timing.Time = skipTime;
            }
            finally
            {
                if (InReplayMode)
                {
                    var inputManager = (KeysInputManager)Ruleset.InputManager;
                    inputManager.ReplayInputManager.HandleSkip();
                }
            }
        }
Exemple #2
0
        /// <summary>
        ///     Ctor
        /// </summary>
        /// <param name="screen"></param>
        public GameplayAudioTiming(GameplayScreen screen)
        {
            Screen = screen;

            try
            {
                if (Screen.IsCalibratingOffset)
                {
                    AudioEngine.Track = new AudioTrack(GameBase.Game.Resources.Get($"Quaver.Resources/Maps/Offset/offset.mp3"));
                }
                else
                {
                    AudioEngine.LoadCurrentTrack();
                    AudioEngine.Track.Rate = ModHelper.GetRateFromMods(ModManager.Mods);
                }

                if (Screen.IsPlayTesting)
                {
                    AudioEngine.Track.Seek(Screen.PlayTestAudioTime);
                    Time = AudioEngine.Track.Time;
                    return;
                }
            }
            catch (AudioEngineException e)
            {
                Logger.Error(e, LogType.Runtime);
            }

            // Set the base time to - the start delay.
            Time = -StartDelay * AudioEngine.Track.Rate;
        }
 /// <summary>
 ///     Initializes the mods for this given play.
 ///     (Recalculates hit windows.)
 /// </summary>
 private void InitializeMods()
 {
     for (var i = 0; i < JudgementWindow.Count; i++)
     {
         JudgementWindow[(Judgement)i] *= ModHelper.GetRateFromMods(Mods);
     }
 }
Exemple #4
0
        /// <summary>
        ///     Updates the text of the metadata with a new map/mods
        ///     Realigns it so it's in the middle.
        /// </summary>
        /// <param name="map"></param>
        public void UpdateAndAlignMetadata(Map map)
        {
            var length = TimeSpan.FromMilliseconds(map.SongLength / ModHelper.GetRateFromMods(ModManager.Mods));

            Mode.UpdateValue(ModeHelper.ToShortHand(map.Mode));
            Bpm.UpdateValue(((int)(map.Bpm * ModHelper.GetRateFromMods(ModManager.Mods))).ToString(CultureInfo.InvariantCulture));
            Length.UpdateValue(length.Hours > 0 ? length.ToString(@"hh\:mm\:ss") : length.ToString(@"mm\:ss"));
            Difficulty.UpdateValue(StringHelper.AccuracyToString((float) map.DifficultyFromMods(ModManager.Mods)).Replace("%", ""));
            LNPercentage.UpdateValue(((int) map.LNPercentage).ToString(CultureInfo.InvariantCulture) + "%");

            for (var i = 0; i < Items.Count; i++)
            {
                var metadata = Items[i];

                if (i == 0)
                {
                    metadata.X = 5;
                    continue;
                }

                var previous = Items[i - 1];
                metadata.X = previous.X + previous.Width + 5 + 5;
            }

            Items.ForEach(x => x.X += (Banner.Width - Items.Last().X) / Items.Count / 2);
        }
Exemple #5
0
        /// <inheritdoc />
        /// <summary>
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            Bindable.Value = Screen.Timing.Time / ModHelper.GetRateFromMods(ModManager.Mods);

            // Only update time each second.
            if (Screen.Timing.Time - TimeLastProgressChange < 1000)
            {
                base.Update(gameTime);
                return;
            }

            TimeLastProgressChange = Screen.Timing.Time;

            // Set the time of the current time
            if (ConfigManager.DisplaySongTimeProgressNumbers.Value)
            {
                if (Bindable.Value > 0)
                {
                    var currTime = new DateTime(1970, 1, 1) + TimeSpan.FromMilliseconds((int)Bindable.Value);
                    CurrentTime.Value = currTime.ToString("mm:ss");
                }

                // Set the time of the time left.
                if (Bindable.MaxValue - Bindable.Value >= 0)
                {
                    var timeLeft = new DateTime(1970, 1, 1) + TimeSpan.FromMilliseconds((int)Bindable.MaxValue - Bindable.Value);

                    // Set the new value.
                    TimeLeft.Value = "-" + timeLeft.ToString("mm:ss");
                }
            }

            base.Update(gameTime);
        }
Exemple #6
0
 /// <summary>
 ///     Makes sure that the speed gameplayModifier selected matches up with the game clock and sets the correct one.
 /// </summary>
 private static void CheckModInconsistencies()
 {
     try
     {
         if (AudioEngine.Track != null && !AudioEngine.Track.IsDisposed)
         {
             AudioEngine.Track.Rate = ModHelper.GetRateFromMods(Mods);
         }
     }
     catch (Exception e)
     {
         // ignored.
     }
 }
Exemple #7
0
        /// <summary>
        ///     Adds a judgement to the hit error at a given hit time.
        /// </summary>
        public void AddJudgement(Judgement j, double hitTime)
        {
            CurrentLinePoolIndex++;

            if (CurrentLinePoolIndex >= PoolSize)
            {
                CurrentLinePoolIndex = 0;
            }

            LineObjectPool[CurrentLinePoolIndex].Tint = SkinManager.Skin.Keys[MapManager.Selected.Value.Mode].JudgeColors[j];

            LineObjectPool[CurrentLinePoolIndex].X     = -(float)hitTime / ModHelper.GetRateFromMods(ModManager.Mods);
            LineObjectPool[CurrentLinePoolIndex].Alpha = 0.5f;
        }
Exemple #8
0
        /// <summary>
        ///     Skips the song to the next object if on a break.
        /// </summary>
        private void SkipToNextObject(bool force = false)
        {
            if (!EligibleToSkip || IsPaused || IsResumeInProgress)
            {
                return;
            }

            if (IsMultiplayerGame && !force)
            {
                if (RequestedToSkipSong)
                {
                    return;
                }

                OnlineManager.Client?.RequestToSkipSong();
                RequestedToSkipSong = true;
                NotificationManager.Show(NotificationLevel.Info, "Requested to skip song. Waiting for all other players to skip!");
                return;
            }

            // Get the skip time of the next object.
            var nextObject = Ruleset.HitObjectManager.NextHitObject.StartTime;
            var skipTime   = nextObject - GameplayAudioTiming.StartDelay * ModHelper.GetRateFromMods(ModManager.Mods);

            try
            {
                // Skip to the time if the audio already played once. If it hasn't, then play it.
                AudioEngine.Track?.Seek(skipTime);
                Timing.Time = AudioEngine.Track.Time;
            }
            catch (Exception e)
            {
                Logger.Error(e, LogType.Runtime);
                Logger.Warning("Trying to skip with no audio file loaded. Still continuing..", LogType.Runtime);
                Timing.Time = skipTime;
            }
            finally
            {
                if (InReplayMode)
                {
                    var inputManager = (KeysInputManager)Ruleset.InputManager;
                    inputManager.ReplayInputManager.HandleSkip();
                }

                // Stop all playing sound effects and move NextSoundEffectIndex ahead.
                CustomAudioSampleCache.StopAll();
                UpdateNextSoundEffectIndex();
            }
        }
Exemple #9
0
        /// <summary>
        ///     Gets the adjacent rate value.
        ///
        ///     For example, if the current rate is 1.0x, the adjacent value would be either 0.95x or 1.1x,
        ///     depending on the argument.
        /// </summary>
        /// <param name="faster">If true, returns the higher rate, otherwise the lower rate.</param>
        /// <returns></returns>
        private static float GetNextRate(bool faster)
        {
            var current    = ModHelper.GetRateFromMods(ModManager.Mods);
            var adjustment = 0.1f;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (current < 1.0f || (current == 1.0f && !faster))
            {
                adjustment = 0.05f;
            }

            var next = current + adjustment * (faster ? 1f : -1f);

            return((float)Math.Round(next, 2));
        }
        /// <summary>
        ///     Initializes the mods for this given play.
        ///     (Recalculates hit windows.)
        /// </summary>
        private void InitializeMods()
        {
            for (var i = 0; i < JudgementWindow.Count; i++)
            {
                JudgementWindow[(Judgement)i] *= ModHelper.GetRateFromMods(Mods);
            }

            if (Mods.HasFlag(ModIdentifier.HeatlthAdjust))
            {
                JudgementHealthWeighting[Judgement.Marv]  = 0.65f;
                JudgementHealthWeighting[Judgement.Perf]  = 0.45f;
                JudgementHealthWeighting[Judgement.Great] = 0.3f;
                JudgementHealthWeighting[Judgement.Good]  = 0.1f;
                JudgementHealthWeighting[Judgement.Okay]  = -2.5f;
                JudgementHealthWeighting[Judgement.Miss]  = -5.0f;
            }
        }
Exemple #11
0
        /// <summary>
        ///     Loads the track for the currently selected map.
        /// </summary>
        public static void LoadCurrentTrack()
        {
            Map = MapManager.Selected.Value;

            if (Track != null && !Track.IsDisposed)
            {
                Track.Dispose();
            }

            Track = new AudioTrack(MapManager.CurrentAudioPath)
            {
                Volume = ConfigManager.VolumeMusic.Value,
                Rate   = ModHelper.GetRateFromMods(ModManager.Mods),
            };

            Track.ToggleRatePitching(ConfigManager.Pitched.Value);
        }
        /// <summary>
        ///     Creates the early and late text labels.
        /// </summary>
        private void CreateEarlyLateText()
        {
            var unscaledLargestHitWindow = LargestHitWindow / ModHelper.GetRateFromMods(Processor.Mods);

            // ReSharper disable once ObjectCreationAsStatement
            new SpriteText(Fonts.SourceSansProSemiBold, $"Late (+{unscaledLargestHitWindow}ms)", 13)
            {
                Parent = this,
                X      = 2
            };

            // ReSharper disable once ObjectCreationAsStatement
            new SpriteText(Fonts.SourceSansProSemiBold, $"Early (-{unscaledLargestHitWindow}ms)", 13)
            {
                Parent    = this,
                Alignment = Alignment.BotLeft,
                X         = 2
            };
        }
Exemple #13
0
        /// <inheritdoc />
        /// <summary>
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            Bindable.Value = Screen.Timing.Time / ModHelper.GetRateFromMods(ModManager.Mods);

            // Only update time each second.
            if (Screen.Timing.Time - TimeLastProgressChange < 1000)
            {
                base.Update(gameTime);
                return;
            }

            TimeLastProgressChange = Screen.Timing.Time;

            // Set the time of the current time
            if (ConfigManager.DisplaySongTimeProgressNumbers.Value)
            {
                if (Bindable.Value > 0)
                {
                    var currTime = new DateTime(1970, 1, 1) + TimeSpan.FromMilliseconds((int)Bindable.Value);
                    CurrentTime.Value = currTime.ToString("mm:ss");
                }

                // Set the time of the time left.
                if (Bindable.MaxValue - Bindable.Value >= 0)
                {
                    var timeLeft = new DateTime(1970, 1, 1) + TimeSpan.FromMilliseconds((int)Bindable.MaxValue - Bindable.Value);

                    // Get the old value.
                    var oldValue = TimeLeft.Value;

                    // Set the new value.
                    TimeLeft.Value = "-" + timeLeft.ToString("mm:ss");

                    // Check if we need to reposition it since it's on the right side of the screen.
                    if (oldValue.Length != TimeLeft.Value.Length)
                    {
                        TimeLeft.X = -TimeLeft.TotalWidth - 10;
                    }
                }
            }

            base.Update(gameTime);
        }
Exemple #14
0
        /// <summary>
        ///     Computes the hit statistics from the hit data.
        /// </summary>
        /// <returns></returns>
        public HitStatistics GetHitStatistics()
        {
            var largestHitWindow = JudgementWindow.Values.Max();
            var hitDifferences   = new List <int>();
            var sum = 0;

            foreach (var breakdown in Stats)
            {
                var hitDifference = breakdown.HitDifference;

                // The LN releases are _not_ scaled here because we want an accurate mean.

                // No need to check for Type == Miss as all of them have hitDifference == int.MinValue.
                if (hitDifference != int.MinValue && Math.Abs(hitDifference) <= largestHitWindow)
                {
                    hitDifferences.Add(hitDifference);
                    sum += hitDifference; // This overflows at like 13 million max judgements.
                }
            }

            double mean = 0.0;
            double standardDeviation = 0.0;

            var count = hitDifferences.Count();

            if (count > 0)
            {
                mean = (double)sum / (double)count;
                standardDeviation = Math.Sqrt(hitDifferences.Average(v => Math.Pow(v - mean, 2)));

                // Undo the rate scaling.
                mean /= ModHelper.GetRateFromMods(Mods);
                // Since variance(ax) = a^2 variance(x), then std(ax) = a std(x)
                standardDeviation /= ModHelper.GetRateFromMods(Mods);
            }

            return(new HitStatistics
            {
                Mean = mean,
                StandardDeviation = standardDeviation
            });
        }
Exemple #15
0
        /// <summary>
        ///     Removes any speed mods from the game and resets the clock
        /// </summary>
        public static void RemoveSpeedMods()
        {
            try
            {
                CurrentModifiersList.RemoveAll(x => x.Type == ModType.Speed);

                if (AudioEngine.Track != null)
                {
                    AudioEngine.Track.Rate = ModHelper.GetRateFromMods(Mods);
                }

                CheckModInconsistencies();

                ModsChanged?.Invoke(typeof(ModManager), new ModsChangedEventArgs(Mods));
                Logger.Debug("Removed all speed modifiers", LogType.Runtime, false);
            }
            catch (Exception e)
            {
                Logger.Error(e, LogType.Runtime);
            }
        }
Exemple #16
0
        /// <summary>
        ///     Calculates the final health weighting values for each judgement from
        ///     average actions per second. <see cref="Qua.GetActionsPerSecond"/>
        ///
        ///     Resource: https://www.desmos.com/calculator/veeobxirvz
        /// </summary>
        protected override void InitializeHealthWeighting()
        {
            if (Mods.HasFlag(ModIdentifier.Autoplay))
            {
                return;
            }

            var density = Map.GetActionsPerSecond(ModHelper.GetRateFromMods(Mods));

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (density == 0 || density >= 12 || double.IsNaN(density))
            {
                return;
            }

            // Set baseline density to 2
            if (density > 0 && density < 2)
            {
                density = 2;
            }

            var values = new Dictionary <Judgement, Tuple <float, float> >
            {
                { Judgement.Marv, new Tuple <float, float>(-0.14f, 2.68f) },
                { Judgement.Perf, new Tuple <float, float>(-0.2f, 3.4f) },
                { Judgement.Great, new Tuple <float, float>(-0.14f, 2.68f) },
                { Judgement.Good, new Tuple <float, float>(0.084f, -0.008f) },
                { Judgement.Okay, new Tuple <float, float>(0.081f, 0.028f) }
            };

            foreach (var item in values)
            {
                var val        = values[item.Key];
                var multiplier = val.Item1 * density + val.Item2;

                var weight = JudgementHealthWeighting[item.Key];
                JudgementHealthWeighting[item.Key] = (float)Math.Round(multiplier * weight, 2, MidpointRounding.ToEven);
            }
        }
Exemple #17
0
        /// <summary>
        ///     Loads the track for the currently selected map.
        /// </summary>
        public static void LoadCurrentTrack()
        {
            Map = MapManager.Selected.Value;

            if (Track != null && !Track.IsDisposed)
            {
                Track.Dispose();
            }

            if (!File.Exists(MapManager.CurrentAudioPath))
            {
                throw new FileNotFoundException($"The audio file at path: {MapManager.CurrentAudioPath} could not be found.");
            }

            Track = new AudioTrack(MapManager.CurrentAudioPath)
            {
                Volume = ConfigManager.VolumeMusic.Value,
                Rate   = ModHelper.GetRateFromMods(ModManager.Mods),
            };

            Track.ToggleRatePitching(ConfigManager.Pitched.Value);
        }
Exemple #18
0
        /// <summary>
        ///     Gets the selected index of the speeds based on the audio rate
        /// </summary>
        /// <returns></returns>
        private int GetSelectedIndex()
        {
            var    rate = ModHelper.GetRateFromMods(ModManager.Mods);
            string rateString;

            switch (rate)
            {
            case 1f:
                rateString = "1.0x";
                break;

            case 2:
                rateString = "2.0x";
                break;

            default:
                rateString = $"{rate}x";
                break;
            }

            return(Speeds.FindIndex(x => x == rateString));
        }
Exemple #19
0
        /// <summary>
        ///     Loads the track for the currently selected map.
        /// </summary>
        public static void LoadCurrentTrack(bool preview = false, int time = 300000)
        {
            Source.Cancel();
            Source.Dispose();
            Source = new CancellationTokenSource();

            Map = MapManager.Selected.Value;
            var token = Source.Token;

            try
            {
                if (Track != null && !Track.IsDisposed)
                {
                    Track.Dispose();
                }

                var newTrack = new AudioTrack(MapManager.CurrentAudioPath, false)
                {
                    Rate = ModHelper.GetRateFromMods(ModManager.Mods),
                };

                token.ThrowIfCancellationRequested();

                Track = newTrack;
                Track.ApplyRate(ConfigManager.Pitched.Value);
            }
            catch (OperationCanceledException e)
            {
            }
            catch (Exception e)
            {
                if (Track != null && !Track.IsDisposed)
                {
                    Track.Dispose();
                }

                Track = new AudioTrackVirtual(time);
            }
        }
        /// <summary>
        ///     Creates the early and late text labels.
        /// </summary>
        private void CreateEarlyLateText()
        {
            var unscaledLargestHitWindow = LargestHitWindow / ModHelper.GetRateFromMods(Processor.Mods);

            // ReSharper disable once ObjectCreationAsStatement
            new SpriteTextBitmap(FontsBitmap.GothamRegular, $"Late (+{unscaledLargestHitWindow} ms)")
            {
                Parent   = this,
                X        = 4,
                Y        = 5,
                FontSize = 14
            };

            // ReSharper disable once ObjectCreationAsStatement
            new SpriteTextBitmap(FontsBitmap.GothamRegular, $"Early (-{unscaledLargestHitWindow} ms)")
            {
                Parent    = this,
                Alignment = Alignment.BotLeft,
                X         = 4,
                Y         = -5,
                FontSize  = 14
            };
        }
        /// <summary>
        ///     Calculate difficulty of a map with given rate
        /// </summary>
        /// <param name="rate"></param>
        public void CalculateDifficulty(ModIdentifier mods)
        {
            // If map does not exist, ignore calculation.
            if (Map == null)
            {
                return;
            }

            // Get song rate from selected mods
            var rate = ModHelper.GetRateFromMods(mods);

            // Compute for overall difficulty
            switch (Map.Mode)
            {
            case (GameMode.Keys4):
                OverallDifficulty = ComputeForOverallDifficulty(rate);
                break;

            case (GameMode.Keys7):
                OverallDifficulty = (ComputeForOverallDifficulty(rate, Hand.Left) + ComputeForOverallDifficulty(rate, Hand.Right)) / 2;
                break;
            }
        }
Exemple #22
0
        /// <summary>
        ///     Loads the track for the currently selected map.
        /// </summary>
        public static void LoadCurrentTrack(bool preview = false)
        {
            Source.Cancel();
            Source.Dispose();
            Source = new CancellationTokenSource();

            Map = MapManager.Selected.Value;
            var token = Source.Token;

            try
            {
                if (Track != null && !Track.IsDisposed)
                {
                    Track.Dispose();
                }

                var newTrack = new AudioTrack(MapManager.CurrentAudioPath, preview)
                {
                    Volume = ConfigManager.VolumeMusic.Value,
                    Rate   = ModHelper.GetRateFromMods(ModManager.Mods),
                };

                token.ThrowIfCancellationRequested();

                Track = newTrack;
                Track.ApplyRate(ConfigManager.Pitched.Value);
            }
            catch (OperationCanceledException e)
            {
                // ignored
            }
            catch (Exception e)
            {
                //Logger.Error(e, LogType.Runtime);
            }
        }
Exemple #23
0
        /// <summary>
        ///     Goes through the score submission process.
        ///     saves score to local database.
        /// </summary>
        private void SubmitScore()
        {
            // Don't save scores if the user quit themself.
            if (Gameplay.HasQuit || Gameplay.InReplayMode)
            {
                return;
            }

            // Don't submit scores at all if the user has ALL misses for their judgements.
            // They basically haven't actually played the map.
            if (ScoreProcessor.CurrentJudgements[Judgement.Miss] == ScoreProcessor.TotalJudgementCount)
            {
                return;
            }

            ThreadScheduler.Run(SaveLocalScore);

            // Don't submit scores if disconnected from the server completely.
            if (OnlineManager.Status.Value == ConnectionStatus.Disconnected)
            {
                return;
            }

            ThreadScheduler.Run(() =>
            {
                Logger.Important($"Beginning to submit score on map: {Gameplay.MapHash}", LogType.Network);

                OnlineManager.Client?.Submit(new OnlineScore(Gameplay.MapHash, Gameplay.ReplayCapturer.Replay,
                                                             ScoreProcessor, ScrollSpeed, ModHelper.GetRateFromMods(ModManager.Mods), TimeHelper.GetUnixTimestampMilliseconds(),
                                                             SteamManager.PTicket));
            });
        }
Exemple #24
0
        /// <summary>
        /// </summary>
        public void UpdateContent()
        {
            Map map;

            if (MapManager.Selected.Value?.Md5Checksum == Game.MapMd5)
            {
                map = MapManager.Selected.Value;
            }
            else
            {
                map = MapManager.FindMapFromMd5(Game.MapMd5);

                // In the event that we don't have the correct version, try to find the
                // alternative one. This is commonly used for situations where one has osu!
                // beatmaps auto-loaded and someone downloads and converts the file to .qua format
                if (map == null && Game.MapMd5 != Game.AlternativeMd5)
                {
                    map = MapManager.FindMapFromMd5(Game.AlternativeMd5);
                }

                MapManager.Selected.Value = map;
            }

            HasMap = map != null;

            if (OnlineManager.CurrentGame.HostSelectingMap)
            {
                ArtistTitle.Text      = "Host is currently selecting a map!";
                Mode.Text             = "Please wait...";
                Creator.Text          = "";
                DifficultyName.Text   = "";
                DifficultyRating.Text = "";
            }
            else
            {
                var diffName = GetDifficultyName();

                ArtistTitle.Text = Game.Map.Replace($"[{diffName}]", "");
                Mode.Text        = $"[{ModeHelper.ToShortHand((GameMode) Game.GameMode)}]";
                Creator.Tint     = Color.White;

                DifficultyRating.Text = map != null ? $"{map.DifficultyFromMods(ModManager.Mods):0.00}" : $"{Game.DifficultyRating:0.00}";
                DifficultyRating.Tint = ColorHelper.DifficultyToColor((float)(map?.DifficultyFromMods(ModManager.Mods) ?? Game.DifficultyRating));
                DifficultyRating.X    = Mode.X + Mode.Width + 8;
                DifficultyName.X      = DifficultyRating.X + DifficultyRating.Width + 2;
                DifficultyName.Text   = " - \"" + diffName + "\"";
            }

            var game = (QuaverGame)GameBase.Game;

            if (map != null)
            {
                ArtistTitle.Tint = Color.White;

                var length = TimeSpan.FromMilliseconds(map.SongLength / ModHelper.GetRateFromMods(ModManager.Mods));
                var time   = length.Hours > 0 ? length.ToString(@"hh\:mm\:ss") : length.ToString(@"mm\:ss");

                if (OnlineManager.CurrentGame.HostSelectingMap)
                {
                    Creator.Text = "";
                }
                else
                {
                    Creator.Text = $"By: {map.Creator} | Length: {time} | BPM: {(int) (map.Bpm * ModHelper.GetRateFromMods(ModManager.Mods))} " +
                                   $"| LNs: {(int) map.LNPercentage}%";
                }

                // Inform the server that we now have the map if we didn't before.
                if (OnlineManager.CurrentGame.PlayersWithoutMap.Contains(OnlineManager.Self.OnlineUser.Id))
                {
                    OnlineManager.Client.HasMultiplayerGameMap();
                }

                if (game.CurrentScreen.Type == QuaverScreenType.Lobby || game.CurrentScreen.Type == QuaverScreenType.Multiplayer ||
                    QuaverScreenManager.QueuedScreen.Type == QuaverScreenType.Multiplayer ||
                    AudioEngine.Map != map)
                {
                    if (BackgroundHelper.Map != MapManager.Selected.Value)
                    {
                        Background.Alpha = 0;

                        var view = Screen.View as MultiplayerScreenView;
                        view?.FadeBackgroundOut();
                        BackgroundHelper.Load(map);
                    }

                    ThreadScheduler.Run(() =>
                    {
                        try
                        {
                            if (AudioEngine.Map != map)
                            {
                                if (!HasMap)
                                {
                                    return;
                                }

                                AudioEngine.LoadCurrentTrack();
                                AudioEngine.Track.Play();
                            }
                        }
                        catch (Exception e)
                        {
                            // ignored
                        }
                    });
                }
            }
            // Let the server know that we don't have the selected map
            else
            {
                ArtistTitle.Tint = Color.Red;

                Creator.Text = Game.MapId != -1 ? "You don't have this map. Click to download!" : "You don't have this map. Download not available!";
                Creator.Tint = Colors.SecondaryAccent;

                if (!OnlineManager.CurrentGame.PlayersWithoutMap.Contains(OnlineManager.Self.OnlineUser.Id))
                {
                    OnlineManager.Client.DontHaveMultiplayerGameMap();
                }

                if (!AudioEngine.Track.IsStopped)
                {
                    AudioEngine.Track.Stop();
                }

                MapManager.Selected.Value = MapManager.Mapsets.First().Maps.First();
            }
        }
Exemple #25
0
        /// <summary>
        /// </summary>
        private void CreateGraph()
        {
            var i = 0;

            foreach (Judgement j in Enum.GetValues(typeof(Judgement)))
            {
                if (j == Judgement.Ghost)
                {
                    continue;
                }

                var color = SkinManager.Skin.Keys[GameMode.Keys4].JudgeColors[j];

                var judgementName = new SpriteTextBitmap(FontsBitmap.GothamRegular, j.ToString().ToUpper())
                {
                    Parent   = this,
                    Y        = i * 50 + 24,
                    X        = 15,
                    Tint     = color,
                    FontSize = 16
                };

                var percentage = Processor.CurrentJudgements[j] == 0 ? 0 : (float)Processor.CurrentJudgements[j] / Processor.TotalJudgementCount;

                var progressBar = new Sprite
                {
                    Parent    = judgementName,
                    Alignment = Alignment.MidLeft,
                    Tint      = color,
                    Height    = 14,
                    Width     = (Width - 300) * percentage,
                    X         = 80,
                };

                if (progressBar.Width <= 1)
                {
                    progressBar.Width = 1;
                }

                var judgementAmount = new SpriteTextBitmap(FontsBitmap.GothamRegular, $"{Processor.CurrentJudgements[j]:N0} ({percentage * 100:0.0}%)")
                {
                    Parent    = progressBar,
                    Alignment = Alignment.MidLeft,
                    Tint      = color,
                    X         = progressBar.Width + 10,
                    FontSize  = 15
                };

                var windows = new SpriteTextBitmap(FontsBitmap.GothamRegular, $"")
                {
                    Parent    = progressBar,
                    Alignment = Alignment.MidLeft,
                    Tint      = color,
                    X         = judgementAmount.X + judgementAmount.Width + 3,
                    FontSize  = 15
                };

                if (Container.StandardizedProcessor != null)
                {
                    windows.Text = $" - {Processor.JudgementWindow[j] / ModHelper.GetRateFromMods(Processor.Mods)} ms";
                }
                else if (Container.Screen.ResultsType == ResultScreenType.Score &&
                         Container.Screen.Score.JudgementWindowPreset != JudgementWindowsDatabaseCache.Standard.Name &&
                         Container.Screen.Score.JudgementWindowPreset != null)
                {
                    switch (j)
                    {
                    case Judgement.Marv:
                        windows.Text = " - " + Container.Screen.Score.JudgementWindowMarv;
                        break;

                    case Judgement.Perf:
                        windows.Text = " - " + Container.Screen.Score.JudgementWindowPerf;
                        break;

                    case Judgement.Great:
                        windows.Text = " - " + Container.Screen.Score.JudgementWindowGreat;
                        break;

                    case Judgement.Good:
                        windows.Text = " - " + Container.Screen.Score.JudgementWindowGood;
                        break;

                    case Judgement.Okay:
                        windows.Text = " - " + Container.Screen.Score.JudgementWindowOkay;
                        break;

                    case Judgement.Miss:
                        windows.Text = " - " + Container.Screen.Score.JudgementWindowMiss;
                        break;
                    }

                    windows.Text += " ms";
                }

                i++;
            }
        }
Exemple #26
0
        /// <summary>
        ///     Creates the progress bar if the user defined it in config.
        /// </summary>
        private void CreateProgressBar()
        {
            if (!ConfigManager.DisplaySongTimeProgress.Value)
            {
                return;
            }

            var skin = SkinManager.Skin.Keys[Screen.Map.Mode];

            ProgressBar = new SongTimeProgressBar(Screen, new Vector2(WindowManager.Width, 4), 0, Screen.Map.Length / ModHelper.GetRateFromMods(ModManager.Mods), 0,
                                                  skin.SongTimeProgressInactiveColor, skin.SongTimeProgressActiveColor)
            {
                Parent    = Container,
                Alignment = Alignment.BotLeft
            };
        }
Exemple #27
0
        /// <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);
        }
        /// <summary>
        ///     Closes the dialog.
        /// </summary>
        public void Close(bool changeMods = true)
        {
            if (isClosing)
            {
                return;
            }

            if (OnlineManager.CurrentGame != null && changeMods)
            {
                if (ModsWhenDialogOpen != ModManager.Mods)
                {
                    var diffRating = OnlineManager.CurrentGame.DifficultyRating;

                    // Only update the difficulty rating when closing if the selected map is still the same.
                    // If the user switches maps, but changes modifiers, it'll be incorrect.
                    if (MapManager.Selected.Value != null && MapManager.Selected.Value.Md5Checksum == OnlineManager.CurrentGame.MapMd5)
                    {
                        diffRating = MapManager.Selected.Value.DifficultyFromMods(ModManager.Mods);
                    }

                    var rateNow = ModHelper.GetRateFromMods(ModManager.Mods);

                    // Change the global mods of the game
                    var rateMod = (long)ModHelper.GetModsFromRate(rateNow);

                    if (rateMod == -1)
                    {
                        rateMod = 0;
                    }

                    var           activeModsWithoutRate  = (long)ModManager.Mods - rateMod;
                    ModIdentifier hostOnlyMods           = 0L;
                    var           onlyHostChangeableMods = ModManager.CurrentModifiersList.FindAll(x => x.OnlyMultiplayerHostCanCanChange);

                    if (onlyHostChangeableMods.Count != 0)
                    {
                        onlyHostChangeableMods.ForEach(x =>
                        {
                            // ReSharper disable once AccessToModifiedClosure
                            activeModsWithoutRate -= (long)x.ModIdentifier;
                            hostOnlyMods          |= x.ModIdentifier;
                        });
                    }

                    if (activeModsWithoutRate == -1)
                    {
                        activeModsWithoutRate = 0;
                    }

                    // If we're on regular free mod mode, when we change the rate,
                    // ReSharper disable once CompareOfFloatsByEqualityOperator
                    if (OnlineManager.CurrentGame.FreeModType == MultiplayerFreeModType.Regular &&
                        (ModHelper.GetRateFromMods(ModsWhenDialogOpen) != rateNow || hostOnlyMods != 0) &&
                        OnlineManager.CurrentGame.Host == OnlineManager.Self.OnlineUser)
                    {
                        OnlineManager.Client?.MultiplayerChangeGameModifiers(rateMod + (long)hostOnlyMods, diffRating);

                        // Change the mods of ourselves minus the mods rate (gets all other activated modes)
                        OnlineManager.Client?.MultiplayerChangePlayerModifiers(activeModsWithoutRate);
                    }
                    // Free mod is enabled, but we haven't done any rate changing, so just
                    // enable player modifiers for us
                    else if (OnlineManager.CurrentGame.FreeModType != MultiplayerFreeModType.None)
                    {
                        // Free Mod + Free Rate
                        if (OnlineManager.CurrentGame.FreeModType.HasFlag(MultiplayerFreeModType.Regular) &&
                            OnlineManager.CurrentGame.FreeModType.HasFlag(MultiplayerFreeModType.Rate))
                        {
                            if (OnlineManager.CurrentGame.Host == OnlineManager.Self.OnlineUser)
                            {
                                OnlineManager.Client?.MultiplayerChangeGameModifiers((long)hostOnlyMods, diffRating);
                            }

                            OnlineManager.Client?.MultiplayerChangePlayerModifiers((long)ModManager.Mods);
                        }
                        // Either Free Mod OR Free Rate
                        else
                        {
                            switch (OnlineManager.CurrentGame.FreeModType)
                            {
                            case MultiplayerFreeModType.Regular:
                                OnlineManager.Client?.MultiplayerChangePlayerModifiers(activeModsWithoutRate);

                                if (OnlineManager.CurrentGame.Host == OnlineManager.Self.OnlineUser)
                                {
                                    OnlineManager.Client?.MultiplayerChangeGameModifiers(rateMod + (long)hostOnlyMods, diffRating);
                                }
                                break;

                            case MultiplayerFreeModType.Rate:
                                OnlineManager.Client?.MultiplayerChangePlayerModifiers((long)ModHelper.GetModsFromRate(rateNow));

                                if (OnlineManager.CurrentGame.Host == OnlineManager.Self.OnlineUser)
                                {
                                    OnlineManager.Client?.MultiplayerChangeGameModifiers(activeModsWithoutRate + (long)hostOnlyMods, diffRating);
                                }
                                break;
                            }
                        }
                    }
                    // We're host & free mod isn't enabled, so change the global game mods
                    else if (OnlineManager.CurrentGame.Host == OnlineManager.Self.OnlineUser)
                    {
                        OnlineManager.Client?.MultiplayerChangeGameModifiers((long)ModManager.Mods, diffRating);
                    }
                }
            }

            isClosing = true;
            InterfaceContainer.Animations.Clear();
            InterfaceContainer.Animations.Add(new Animation(AnimationProperty.Y, Easing.OutQuint, InterfaceContainer.Y, InterfaceContainer.Height, 600));
            ThreadScheduler.RunAfter(() => DialogManager.Dismiss(this), 450);
        }
Exemple #29
0
        /// <summary>
        ///     Creates the local and global offset fix buttons.
        /// </summary>
        private void CreateOffsetFixButtons()
        {
            // Don't draw the buttons if we don't have the hit stats (and therefore don't know the
            // values to adjust the offset by).
            if (Processor.Stats == null)
            {
                return;
            }

            var availableWidth = Width - VerticalDividerLine.X;
            var buttonPadding  = 15;
            var buttonWidth    = (availableWidth - buttonPadding * 3) / 2;

            var localOffsetButton = new BorderedTextButton("Fix Local Offset", Colors.MainAccent,
                                                           (o, e) =>
            {
                // Local offset is scaled with rate, so the adjustment depends on the rate the
                // score was played on.
                var change    = HitStatistics.Mean * ModHelper.GetRateFromMods(Processor.Mods);
                var newOffset = (int)Math.Round(ResultScreen.Map.LocalOffset - change);

                DialogManager.Show(new ConfirmCancelDialog($"Local offset will be changed from {ResultScreen.Map.LocalOffset} ms to {newOffset} ms.",
                                                           (o_, e_) =>
                {
                    ResultScreen.Map.LocalOffset = newOffset;
                    MapDatabaseCache.UpdateMap(ResultScreen.Map);
                    NotificationManager.Show(NotificationLevel.Success, $"Local offset was set to {ResultScreen.Map.LocalOffset} ms.");
                }));
            })
            {
                Parent = this,
                X      = VerticalDividerLine.X + buttonPadding,
                Y      = BottomHorizontalDividerLine.Y - 15 - 25,
                Height = 30,
                Width  = buttonWidth,
                Text   =
                {
                    Font     = Fonts.SourceSansProSemiBold,
                    FontSize = 13
                }
            };
            var globalOffsetButton = new BorderedTextButton("Fix Global Offset", Colors.MainAccent,
                                                            (o, e) =>
            {
                var newOffset = (int)Math.Round(ConfigManager.GlobalAudioOffset.Value + HitStatistics.Mean);

                DialogManager.Show(new ConfirmCancelDialog($"Global offset will be changed from {ConfigManager.GlobalAudioOffset.Value} ms to {newOffset} ms.",
                                                           (o_, e_) =>
                {
                    ConfigManager.GlobalAudioOffset.Value = newOffset;
                    NotificationManager.Show(NotificationLevel.Success, $"Global offset was set to {ConfigManager.GlobalAudioOffset.Value} ms.");
                }));
            })
            {
                Parent = this,
                X      = localOffsetButton.X + localOffsetButton.Width + buttonPadding,
                Y      = BottomHorizontalDividerLine.Y - 15 - 25,
                Height = 30,
                Width  = buttonWidth,
                Text   =
                {
                    Font     = Fonts.SourceSansProSemiBold,
                    FontSize = 13
                }
            };
        }
        /// <inheritdoc />
        /// <summary>
        /// </summary>
        /// <param name="container"></param>
        /// <param name="item"></param>
        /// <param name="index"></param>
        /// <param name="header"></param>
        public ResultMultiplayerScoreboardUser(PoolableScrollContainer <ScoreboardUser> container, ScoreboardUser item, int index, ResultMultiplayerScoreboardTableHeader header)
            : base(container, item, index)
        {
            Header = header;
            Size   = new ScalableVector2(container.Width, HEIGHT);
            Alpha  = 0.85f;

            Button = new ResultMultiplayerScoreboardUserButton(Item, container)
            {
                Parent = this,
                Size   = Size,
                UsePreviousSpriteBatchOptions = true
            };

            // ReSharper disable once ObjectCreationAsStatement
            var rank = new SpriteTextBitmap(FontsBitmap.GothamRegular, $"{item.Rank}.")
            {
                Parent    = this,
                Alignment = Alignment.MidLeft,
                X         = 20,
                FontSize  = 16,
                Tint      = Item.Type == ScoreboardUserType.Self ? Colors.SecondaryAccent : Color.White,
                UsePreviousSpriteBatchOptions = true
            };

            var avatar = new Sprite
            {
                Parent    = this,
                Alignment = Alignment.MidLeft,
                Size      = new ScalableVector2(32, 32),
                X         = 56,
                Image     = item.Avatar.Image,
                UsePreviousSpriteBatchOptions = true
            };

            avatar.AddBorder(Color.White, 2);

            var username = new SpriteTextBitmap(FontsBitmap.GothamRegular, item.UsernameRaw)
            {
                Parent    = this,
                Alignment = Alignment.MidLeft,
                X         = avatar.X + avatar.Width + 16,
                FontSize  = 16,
                Tint      = Item.Type == ScoreboardUserType.Self ? Colors.SecondaryAccent : Color.White,
                UsePreviousSpriteBatchOptions = true
            };

            if (item.Processor == null)
            {
                return;
            }

            CreateData(new Dictionary <string, string>
            {
                { "Rating", item.CalculateRating().ToString("00.00") },
                { "Grade", "" },
                { "Accuracy", StringHelper.AccuracyToString(item.Processor.Accuracy) },
                { "Max Combo", item.Processor.MaxCombo + "x" },
                { "Marv", item.Processor.CurrentJudgements[Judgement.Marv].ToString() },
                { "Perf", item.Processor.CurrentJudgements[Judgement.Perf].ToString() },
                { "Great", item.Processor.CurrentJudgements[Judgement.Great].ToString() },
                { "Good", item.Processor.CurrentJudgements[Judgement.Good].ToString() },
                { "Okay", item.Processor.CurrentJudgements[Judgement.Okay].ToString() },
                { "Miss", item.Processor.CurrentJudgements[Judgement.Miss].ToString() },
                { "Mods", item.Processor.Mods <= 0 ? "None" : ModHelper.GetModsString(ModHelper.GetModsFromRate(ModHelper.GetRateFromMods(item.Processor.Mods))) }
            });

            // ReSharper disable once ObjectCreationAsStatement
            new Sprite
            {
                Parent    = this,
                Alignment = Alignment.BotLeft,
                Size      = new ScalableVector2(Width, 1),
                Alpha     = 0.3f
            };
        }