Skip to content

Commit

Permalink
Fix score tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
qe201020335 committed Jul 15, 2023
1 parent 93854c1 commit 174ec15
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 78 deletions.
2 changes: 1 addition & 1 deletion SongPlayHistory/Installers/ScoreTrackerInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class ScoreTrackerInstaller : Installer<ScoreTrackerInstaller>
public override void InstallBindings()
{
Plugin.Log.Warn("Binding ScoreTracker");
Container.BindInterfacesTo<ScoreTracker>().AsSingle().NonLazy();
Container.BindInterfacesTo<ScoreTracker>().AsSingle();
}
}
}
59 changes: 35 additions & 24 deletions SongPlayHistory/RecordsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,8 @@ private void OnGameSceneLoaded()
var practiceSettings = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData?.practiceSettings;
_isPractice = practiceSettings != null;
_isReplay = Utils.Utils.IsInReplay();
ScoreTracker.MaxRawScore = null;
ScoreTracker.RawScore = null;
ScoreTracker.MultipliedScore = null;
ScoreTracker.EnergyDidReach0 = false;
ScoreTracker.FailScoreRecord = null;
}

private void OnLevelFinished(object scene, LevelFinishedEventArgs eventArgs)
Expand All @@ -125,11 +123,13 @@ private void OnLevelFinished(object scene, LevelFinishedEventArgs eventArgs)
}

var result = ((LevelFinishedWithResultsEventArgs)eventArgs).CompletionResults;
var energyDidReach0 = ScoreTracker.EnergyDidReach0;
var failRecord = ScoreTracker.FailScoreRecord;

if (eventArgs.LevelType == LevelType.Multiplayer)
{
var beatmap = ((MultiplayerLevelScenesTransitionSetupDataSO)scene).difficultyBeatmap;
SaveRecord(beatmap, result, true);
SaveRecord(beatmap, result, true, energyDidReach0, failRecord);
}
else
{
Expand All @@ -140,7 +140,7 @@ private void OnLevelFinished(object scene, LevelFinishedEventArgs eventArgs)
return;
}
var beatmap = ((StandardLevelScenesTransitionSetupDataSO)scene).difficultyBeatmap;
SaveRecord(beatmap, result, false);
SaveRecord(beatmap, result, false, energyDidReach0, failRecord);
}
}

Expand All @@ -161,7 +161,7 @@ public IList<Record> GetRecords(IDifficultyBeatmap beatmap)
return new List<Record>();
}

private void SaveRecord(IDifficultyBeatmap? beatmap, LevelCompletionResults? result, bool isMultiplayer)
private void SaveRecord(IDifficultyBeatmap? beatmap, LevelCompletionResults? result, bool isMultiplayer, bool energyDidReach0, ScoreRecord? failRecord)
{
if (beatmap == null || result == null)
{
Expand All @@ -183,46 +183,57 @@ private void SaveRecord(IDifficultyBeatmap? beatmap, LevelCompletionResults? res

// We now keep failed records.
var cleared = result.levelEndStateType == LevelCompletionResults.LevelEndStateType.Cleared;
var softFailed = ScoreTracker.EnergyDidReach0;

var submissionDisabled = ScoreSubmission.WasDisabled || ScoreSubmission.Disabled || ScoreSubmission.ProlongedDisabled;
// If submissionDisabled = true, we assume custom gameplay modifiers are applied.
var param = ParamHelper.ModsToParam(result.gameplayModifiers, softFailed);
var noFailEnabled = result.gameplayModifiers.noFailOn0Energy;

_logger.Debug($"Cleared: {cleared}, NoFail: {noFailEnabled}, SoftFailed: {energyDidReach0}, FailRecord: {failRecord}");

var param = ParamHelper.ModsToParam(result.gameplayModifiers, energyDidReach0);
param |= submissionDisabled ? Param.SubmissionDisabled : 0;
param |= isMultiplayer ? Param.Multiplayer : 0;

var time = DateTimeOffset.Now.ToUnixTimeMilliseconds();
Record record;

if (cleared && softFailed && ScoreTracker.RawScore != null && ScoreTracker.MultipliedScore != null)
if (cleared && energyDidReach0 && failRecord != null)
{
// use our tracked values at the time of soft fail
record = new Record
{
Date = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
ModifiedScore = ScoreTracker.RawScore.Value,
RawScore = ScoreTracker.MultipliedScore.Value,
LastNote = ScoreTracker.NotesPassed,
Date = time,
ModifiedScore = failRecord.Value.RawScore,
RawScore = failRecord.Value.ModifiedScore,
LastNote = failRecord.Value.NotesPassed,
Param = (int) param,
MaxRawScore = failRecord.Value.MaxRawScore
};
}
else if (!cleared && noFailEnabled && energyDidReach0 && failRecord != null)
{
// No fail is enabled, but level still failed (for example, thr FailButton mod)
record = new Record
{
Date = time,
ModifiedScore = failRecord.Value.RawScore,
RawScore = failRecord.Value.ModifiedScore,
LastNote = failRecord.Value.NotesPassed,
Param = (int) param,
MaxRawScore = ScoreTracker.MaxRawScore
MaxRawScore = failRecord.Value.MaxRawScore
};
}
else
{
record = new Record
{
Date = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
Date = time,
ModifiedScore = result.modifiedScore,
RawScore = result.multipliedScore,
LastNote = cleared ? -1 : result.goodCutsCount + result.badCutsCount + result.missedCount,
Param = (int) param,
MaxRawScore = cleared ? null : ScoreTracker.MaxRawScore
MaxRawScore = cleared ? null : failRecord?.MaxRawScore
};
}



_logger.Info($"Saving result.");
_logger.Debug($"Record: {record.ToShortString()}");

_logger.Info($"Saving result. Record: {record.ToShortString()}");

var beatmapCharacteristicName = beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName;
var difficulty = $"{beatmap.level.levelID}___{(int)beatmap.difficulty}___{beatmapCharacteristicName}";
Expand Down
125 changes: 72 additions & 53 deletions SongPlayHistory/Utils/ScoreTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,93 +6,112 @@ namespace SongPlayHistory.Utils
{
public class ScoreTracker : IInitializable, IDisposable
{
public static int? MaxRawScore { get; internal set; } = null;
public static int? RawScore { get; internal set; } = null;
private int _maxRawScore;
private int _rawScore;
private int _modifiedScore;
private int _notesPassed;

public static int? MultipliedScore { get; internal set; } = null;
public static bool EnergyDidReach0 { get; internal set; } = false;
public static int NotesPassed { get; private set; } = 0;

/**
* Score record of when the energy first reached 0
*/
public static ScoreRecord? FailScoreRecord { get; internal set; } = null;

[InjectOptional]
private readonly IScoreController? _scoreController = null;
[Inject]
private readonly IScoreController _scoreController = null!;

[InjectOptional]
private readonly IGameEnergyCounter? _energyCounter = null;
[Inject]
private readonly IGameEnergyCounter _energyCounter = null!;

[InjectOptional]
private readonly BeatmapObjectManager? _beatmapObjectManager = null;
[Inject]
private readonly BeatmapObjectManager _beatmapObjectManager = null!;

[Inject]
private readonly SiraLog _logger = null!;

public void Initialize()
{
MaxRawScore = null;
RawScore = null;
MultipliedScore = null;
_maxRawScore = 0;
_rawScore = 0;
_modifiedScore = 0;
EnergyDidReach0 = false;
NotesPassed = 0;
if (_scoreController != null && _energyCounter != null && _beatmapObjectManager != null)
{
_energyCounter.gameEnergyDidReach0Event -= OnEnergyDidReach0;
_energyCounter.gameEnergyDidReach0Event += OnEnergyDidReach0;
_scoreController.scoringForNoteFinishedEvent -= OnScoreChanged;
_scoreController.scoringForNoteFinishedEvent += OnScoreChanged;
_beatmapObjectManager.noteWasCutEvent -= OnNoteCut;
_beatmapObjectManager.noteWasCutEvent += OnNoteCut;
_beatmapObjectManager.noteWasMissedEvent -= OnNoteMiss;
_beatmapObjectManager.noteWasMissedEvent += OnNoteMiss;
}
else
{
_logger.Warn("scoreController or energyCounter or beatmapObjectManager is null!");
}
_notesPassed = 0;

_energyCounter.gameEnergyDidReach0Event -= OnEnergyDidReach0;
_energyCounter.gameEnergyDidReach0Event += OnEnergyDidReach0;
_scoreController.scoringForNoteFinishedEvent -= OnScoreChanged;
_scoreController.scoringForNoteFinishedEvent += OnScoreChanged;
_beatmapObjectManager.noteWasCutEvent -= OnNoteCut;
_beatmapObjectManager.noteWasCutEvent += OnNoteCut;
_beatmapObjectManager.noteWasMissedEvent -= OnNoteMiss;
_beatmapObjectManager.noteWasMissedEvent += OnNoteMiss;
}

private void OnNoteCut(NoteController noteController, in NoteCutInfo noteCutInfo)
{
NotesPassed++;
_notesPassed++;
}

private void OnNoteMiss(NoteController noteController)
{
NotesPassed++;
_notesPassed++;
}

private void OnEnergyDidReach0()
{
if (EnergyDidReach0) return;

EnergyDidReach0 = true;
MaxRawScore = _scoreController?.immediateMaxPossibleMultipliedScore;
RawScore = _scoreController?.multipliedScore;
_logger.Info($"Energy reached 0! Notes fired: {NotesPassed} Scores w/o modifiers: {RawScore}/{MaxRawScore}");
_maxRawScore = _scoreController.immediateMaxPossibleMultipliedScore;
_modifiedScore = _scoreController.modifiedScore;
_rawScore = _scoreController.multipliedScore;
_logger.Info($"Energy reached 0! Notes fired: {_notesPassed}, Scores: {_rawScore}/{_modifiedScore}/{_maxRawScore}");

FailScoreRecord = new ScoreRecord(
energyDidReach0:true,
rawScore:_rawScore,
modifiedScore:_modifiedScore,
maxRawScore:_maxRawScore,
notesPassed:_notesPassed);
}

private void OnScoreChanged(ScoringElement _)
{
if (!EnergyDidReach0)
{
MaxRawScore = _scoreController?.immediateMaxPossibleMultipliedScore;
RawScore = _scoreController?.multipliedScore;
}
_maxRawScore = _scoreController.immediateMaxPossibleMultipliedScore;
_modifiedScore = _scoreController.modifiedScore;
_rawScore = _scoreController.multipliedScore;
}

public void Dispose()
{
if (_energyCounter != null)
{
_energyCounter.gameEnergyDidReach0Event -= OnEnergyDidReach0;
}

if (_scoreController != null)
{
_scoreController.scoringForNoteFinishedEvent -= OnScoreChanged;
}
_energyCounter.gameEnergyDidReach0Event -= OnEnergyDidReach0;
_scoreController.scoringForNoteFinishedEvent -= OnScoreChanged;
_beatmapObjectManager.noteWasCutEvent -= OnNoteCut;
_beatmapObjectManager.noteWasMissedEvent -= OnNoteMiss;
}
}

public struct ScoreRecord
{
public readonly bool EnergyDidReach0;
public readonly int MaxRawScore;
public readonly int RawScore;
public readonly int ModifiedScore;
public readonly int NotesPassed;

if (_beatmapObjectManager != null)
{
_beatmapObjectManager.noteWasCutEvent -= OnNoteCut;
_beatmapObjectManager.noteWasMissedEvent -= OnNoteMiss;
}
internal ScoreRecord(bool energyDidReach0, int rawScore, int modifiedScore, int maxRawScore, int notesPassed)
{
EnergyDidReach0 = energyDidReach0;
RawScore = rawScore;
ModifiedScore = modifiedScore;
MaxRawScore = maxRawScore;
NotesPassed = notesPassed;
}

public override string ToString()
{
return $"EnergyDidReach0 {EnergyDidReach0}, Notes fired: {NotesPassed}, Scores: {RawScore}/{ModifiedScore}/{MaxRawScore}";
}
}
}

0 comments on commit 174ec15

Please sign in to comment.