예제 #1
0
        // Purposefully ignore modifiers here - only 2 maps have them enabled and it doesn't make much sense to just filter to those two
        private static float GetHighestPP(IPreviewBeatmapLevel previewBeatmapLevel, bool ppGain)
        {
            float maxPP = 0;
            var   id    = SongDataUtils.GetHash(previewBeatmapLevel.levelID);

            // Check if in SDC
            if (SongDataCore.Plugin.Songs.Data.Songs.ContainsKey(id))
            {
                // Loop through each diff
                foreach (var diff in SongDataCore.Plugin.Songs.Data.Songs[id].diffs)
                {
                    var difficulty = SongDataUtils.GetBeatmapDifficulty(diff.diff);
                    var songID     = new SongID(id, difficulty);
                    // Only go through ranked songs
                    if (SongDataUtils.IsRankedSong(songID))
                    {
                        float pp = PPUtils.CalculatePP(songID, AccLoader.instance.GetAcc(songID));
                        if (ppGain)
                        {
                            pp = PPUtils.GetPPGain(pp, songID);
                        }
                        maxPP = pp > maxPP ? pp : maxPP;
                    }
                }
                return(maxPP);
            }
            return(0);
        }
예제 #2
0
        public float GetAcc(SongID songID)
        {
            // First check for song specific accuracy
            if (_songSpecificAcc.ContainsKey(songID))
            {
                return(RoundedAcc(_songSpecificAcc[songID]));
            }

            double bestAcc = 0;

            // Next check for max of current best acc and star acc
            if (ProfileDataLoader.instance.songDataInfo.ContainsKey(songID))
            {
                bestAcc = ProfileDataLoader.instance.songDataInfo[songID].acc;
            }

            // Next check for star acc
            var star = SongDataUtils.GetRoundedStars(songID);

            if (_starAcc.ContainsKey(star))
            {
                bestAcc = Math.Max(bestAcc, _starAcc[star]);
            }

            if (bestAcc > 0)
            {
                return(RoundedAcc(bestAcc));
            }

            // Finally resort to default
            return(Config.defaultAcc);
        }
예제 #3
0
        IEnumerator FindDifficultyBeatmap()
        {
            yield return(new WaitUntil(() => BS_Utils.Plugin.LevelData.IsSet));

            _difficultyBeatmap = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap;
            _songID            = new SongID(SongDataUtils.GetHash(_difficultyBeatmap.level.levelID), _difficultyBeatmap.difficulty);
            _rawPP             = SongDataUtils.GetRawPP(_songID);

            // modifiers
            var gameplayModifiersModelSO = Resources.FindObjectsOfTypeAll <GameplayModifiersModelSO>().FirstOrDefault();
            var gameplayModifiers        = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.gameplayModifiers;

            _multiplier = gameplayModifiersModelSO.GetTotalMultiplier(gameplayModifiers);
            _multiplier = (Config.ignoreNoFail && gameplayModifiers.noFail) ? _multiplier + 0.5 : _multiplier;

            // Only update for ranked songs
            if (SongDataUtils.IsRankedSong(_songID))
            {
                yield return(new WaitUntil(() => _beatmapObjectManager != null));

                _beatmapObjectManager.noteWasCutEvent    += OnNoteCut;
                _beatmapObjectManager.noteWasMissedEvent += OnNoteMissed;

                yield return(new WaitUntil(() => _scoreController != null));

                _scoreController.scoreDidChangeEvent += OnScoreChange;
                if (!Config.hideOnStart)
                {
                    UpdateCounter();
                }
            }
        }
예제 #4
0
        public void ModifiersChanged()
        {
            var gameplayModifiersPanelController = Resources.FindObjectsOfTypeAll <GameplayModifiersPanelController>().FirstOrDefault();

            _modifiers = gameplayModifiersPanelController.GetPrivateField <GameplayModifiers>("_gameplayModifiers");
            if (SongDataUtils.IsRankedSong(_id))
            {
                SetPPText(PPUtils.AllowedModifiers(_id.id, _modifiers));
            }
        }
예제 #5
0
        public void LevelCleared(StandardLevelScenesTransitionSetupDataSO standardLevelScenesTransitionSetupDataSO, LevelCompletionResults levelCompletionResults)
        {
            Logger.log.Debug("Level cleared");
            // Score submission disabled or using practice mode
            if (BS_Utils.Gameplay.ScoreSubmission.WasDisabled || BS_Utils.Gameplay.ScoreSubmission.ProlongedDisabled ||
                ((GameplayCoreSceneSetupData)standardLevelScenesTransitionSetupDataSO.sceneSetupDataArray.First(x => x.GetType().Equals(typeof(GameplayCoreSceneSetupData)))).practiceSettings != null)
            {
                Logger.log.Debug("Practice mode or score disabled");
                return;
            }

            var gameplayCoreSceneSetupData = ((GameplayCoreSceneSetupData)standardLevelScenesTransitionSetupDataSO.sceneSetupDataArray[1]);
            var difficultyBeatmap          = gameplayCoreSceneSetupData.difficultyBeatmap;

            SongID songID = SongDataUtils.GetSongID(difficultyBeatmap);

            // I don't like putting play history here but until I do a refactor I'm gonna keep it here
            if (SongDataUtils.IsRankedSong(songID) || Config.playHistory)
            {
                Logger.log.Debug("Beat song");
                GameplayModifiers modifiers = new GameplayModifiers(levelCompletionResults.gameplayModifiers);
                // Remove positive modifiers if not allowed
                if (!PPUtils.AllowedModifiers(songID.id, modifiers))
                {
                    Logger.log.Debug("Using invalid modifiers, removing from score");
                    modifiers = BeatSaberUtils.RemovePositiveModifiers(modifiers);
                }

                var    multiplier = levelCompletionResults.gameplayModifiersModel.GetTotalMultiplier(modifiers);
                var    score      = levelCompletionResults.rawScore * multiplier;
                var    maxScore   = ScoreModel.MaxRawScoreForNumberOfNotes(difficultyBeatmap.beatmapData.notesCount);
                double acc        = (double)score / (double)maxScore;
                Logger.log.Debug($"acc: {acc}");

                if (SongDataUtils.IsRankedSong(songID))
                {
                    SubmitPlay(songID, acc);
                }
                else
                {
                    PlayHistoryTracker.UpdatePlayHistory(songID, acc);
                }
            }
        }
예제 #6
0
        // Loops through all songs and finds the highest star difficulty saved (rounded to nearest multiple of starRange)
        private static double CalculateMaxStarValue()
        {
            double maxStarValue = 0;

            foreach (var kvp in ProfileDataLoader.instance.songDataInfo)
            {
                if (SongDataCore.Plugin.Songs.Data.Songs.TryGetValue(kvp.Key.id, out var song))
                {
                    var difficultyStats = SongDataCore.Plugin.Songs.Data.Songs[kvp.Key.id].diffs;
                    foreach (var difficultyStat in difficultyStats)
                    {
                        if (difficultyStat.diff.Equals(SongDataUtils.GetDifficultyAsString(kvp.Key.difficulty)))
                        {
                            var star = SongDataUtils.GetRoundedStars(difficultyStat.star);
                            maxStarValue = star > maxStarValue ? star : maxStarValue;
                        }
                    }
                }
            }

            return(Math.Round(maxStarValue, 2));
        }
예제 #7
0
        public override void CounterInit()
        {
            var id = SongDataUtils.GetHash(difficultyBeatmap.level.levelID);

            songID = new SongID(id, difficultyBeatmap.difficulty);

            // Don't show anything for unranked songs or if data not initialized
            if (!ppUtils.DataInitialized() || !ppUtils.IsRanked(songID))
            {
                return;
            }

            var gameplayModifiersModelSO = IPA.Utilities.FieldAccessor <RelativeScoreAndImmediateRankCounter, GameplayModifiersModelSO> .Get(relativeScoreAndImmediateRank, "_gameplayModifiersModel");

            GameplayModifiers updatedModifiers = ppUtils.AllowedPositiveModifiers(songID) ?
                                                 gameplayModifiers : GameplayModifierUtils.RemovePositiveModifiers(gameplayModifiers);

            _multiplier = GameplayModifierUtils.CalculateMultiplier(gameplayModifiersModelSO, updatedModifiers);

            counter          = CanvasUtility.CreateTextFromSettings(Settings);
            counter.fontSize = 3;

            relativeScoreAndImmediateRank.relativeScoreOrImmediateRankDidChangeEvent += ScoreUpdated;
            UpdateCounterText(ppUtils.CalculatePP(songID, _multiplier, ppUtils.AllowedPositiveModifiers(songID)));

            if (PluginSettings.Instance.relativeGain)
            {
                var highScore = playerDataModel.playerData.GetPlayerLevelStatsData(difficultyBeatmap).highScore;
                if (highScore == 0)
                {
                    _pbPP = 0;
                    return;
                }

                var maxScore = ScoreModel.ComputeMaxMultipliedScoreForBeatmap(beatmapData);
                var acc      = (float)highScore / maxScore;
                _pbPP = ppUtils.CalculatePP(songID, acc, ppUtils.AllowedPositiveModifiers(songID));
            }
        }
예제 #8
0
        internal void Refresh(string id)
        {
            if (!Config.showInfo)
            {
                _parentObject.SetActive(false);
                return;
            }

            try
            {
                IDifficultyBeatmap difficultyBeatmap = _standardLevelDetailView.selectedDifficultyBeatmap;
                var newId = new ProfileDataLoader.SongID(id, difficultyBeatmap.difficulty);

                if (SongDataUtils.IsRankedSong(newId))
                {
                    _parentObject.SetActive(true);
                    _rawPP = SongDataUtils.GetRawPP(newId);
                    // Only load the acc in when a new song is selected
                    if (_id == null || !newId.Equals(_id))
                    {
                        _id = newId;
                        LoadAcc();
                    }

                    SetPPText(PPUtils.AllowedModifiers(_id.id, _modifiers));
                }
                else
                {
                    _parentObject.SetActive(false);
                }
            }
            catch (Exception)
            {
                Logger.log.Debug($"error with difficulty for song {id}");
                _parentObject.SetActive(false);
            }
        }
예제 #9
0
        public static void CalculateAcc()
        {
            Logger.log.Debug("Calculating star acc");
            var range = Config.starRange;
            Dictionary <double, double> acc    = new Dictionary <double, double>();
            Dictionary <double, int>    counts = new Dictionary <double, int>();

            // Need SongDataCore data
            if (!SongDataCore.Plugin.Songs.IsDataAvailable())
            {
                return;
            }

            // Initialize some helper vars
            var numberOfScores = Config.starAccChoice.Equals(CalculationType.Max) ? 1 : Config.numberOfScores;
            var maxScores      = new Dictionary <double, List <double> >();
            var maxStarValue   = CalculateMaxStarValue();
            var averageAll     = Config.starAccChoice.Equals(CalculationType.AverageOfAll);

            // Initialize dicts
            for (double star = 0.00; star <= maxStarValue + 2 * Config.starRange; star += Config.starRange)
            {
                star         = SongDataUtils.GetRoundedStars(star);
                acc[star]    = 0;
                counts[star] = 0;
            }

            foreach (var kvp in ProfileDataLoader.instance.songDataInfo)
            {
                // If star data not available for song, skip it
                double star;
                try
                {
                    star = SongDataUtils.GetRoundedStars(kvp.Key);
                }
                catch (Exception e)
                {
                    Logger.log.Debug($"Couldn't get star rating for {kvp.Key.id}");
                    continue;
                }

                // Will definitely be updating acc
                if (averageAll || counts[star] < numberOfScores)
                {
                    acc[star]     = ((acc[star] * counts[star]) + kvp.Value.acc) / (counts[star] + 1);
                    counts[star] += 1;
                    // update maxScores
                    if (!averageAll)
                    {
                        // first score for given star rating
                        if (!maxScores.ContainsKey(star))
                        {
                            maxScores[star] = new List <double>();
                        }
                        maxScores[star].Add(kvp.Value.acc);
                        maxScores[star].Sort(); // List is small enough to not matter
                    }
                }
                // Better than the lowest sore, update average acc
                else if (kvp.Value.acc > maxScores[star].First())
                {
                    var accWithoutLowerScore = acc[star] * counts[star] - maxScores[star].First();
                    acc[star] = (accWithoutLowerScore + kvp.Value.acc) / (counts[star]);
                    // update maxScores
                    maxScores[star].RemoveAt(0);
                    maxScores[star].Add(kvp.Value.acc);
                    maxScores[star].Sort();
                }
            }

            if (Config.accOverride)
            {
                CleanupStarAcc(ref acc);
            }

            Logger.log.Debug("Finished calculating star acc");
            SaveFile(acc);
        }
예제 #10
0
 public void OnLevelSelected(LevelCollectionViewController levelCollectionViewController, IPreviewBeatmapLevel previewBeatmapLevel)
 {
     PP_HelperController.instance.setId(SongDataUtils.GetHash(previewBeatmapLevel.levelID));
 }