mirror of
https://github.com/ppy/osu.git
synced 2025-02-20 19:35:34 +08:00
Add LegacyScoreInfo for statistics preservation/conversion
This commit is contained in:
parent
1a6c2022ea
commit
8fcb75809d
@ -9,6 +9,7 @@ using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Scoring.Legacy;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
@ -18,11 +19,12 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
protected new CatchDifficultyAttributes Attributes => (CatchDifficultyAttributes)base.Attributes;
|
||||
|
||||
private Mod[] mods;
|
||||
private int countGreat;
|
||||
private int countGood;
|
||||
private int countKatu;
|
||||
private int countMeh;
|
||||
private int countMiss;
|
||||
|
||||
private int fruitsHit;
|
||||
private int ticksHit;
|
||||
private int tinyTicksHit;
|
||||
private int tinyTicksMissed;
|
||||
private int misses;
|
||||
|
||||
public CatchPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score)
|
||||
: base(ruleset, beatmap, score)
|
||||
@ -32,11 +34,14 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
public override double Calculate(Dictionary<string, double> categoryDifficulty = null)
|
||||
{
|
||||
mods = Score.Mods;
|
||||
countGreat = Convert.ToInt32(Score.Statistics[HitResult.Great]);
|
||||
countGood = Convert.ToInt32(Score.Statistics[HitResult.Good]);
|
||||
countKatu = Convert.ToInt32(Score.Statistics[HitResult.Ok]);
|
||||
countMeh = Convert.ToInt32(Score.Statistics[HitResult.Meh]);
|
||||
countMiss = Convert.ToInt32(Score.Statistics[HitResult.Miss]);
|
||||
|
||||
var legacyScore = Score as LegacyScoreInfo;
|
||||
|
||||
fruitsHit = legacyScore?.Count300 ?? Score.Statistics[HitResult.Perfect];
|
||||
ticksHit = legacyScore?.Count100 ?? 0;
|
||||
tinyTicksHit = legacyScore?.Count50 ?? 0;
|
||||
tinyTicksMissed = legacyScore?.CountKatu ?? 0;
|
||||
misses = Score.Statistics[HitResult.Miss];
|
||||
|
||||
// Don't count scores made with supposedly unranked mods
|
||||
if (mods.Any(m => !m.Ranked))
|
||||
@ -57,7 +62,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
value *= lengthBonus;
|
||||
|
||||
// Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available
|
||||
value *= Math.Pow(0.97f, countMiss);
|
||||
value *= Math.Pow(0.97f, misses);
|
||||
|
||||
// Combo scaling
|
||||
float beatmapMaxCombo = Attributes.MaxCombo;
|
||||
@ -92,8 +97,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
}
|
||||
|
||||
private float accuracy() => totalHits() == 0 ? 0 : MathHelper.Clamp((float)totalSuccessfulHits() / totalHits(), 0f, 1f);
|
||||
private int totalHits() => countMeh + countGood + countGreat + countMiss + countKatu;
|
||||
private int totalSuccessfulHits() => countMeh + countGood + countGreat;
|
||||
private int totalComboHits() => countMiss + countGood + countGreat;
|
||||
private int totalHits() => tinyTicksHit + ticksHit + fruitsHit + misses + tinyTicksMissed;
|
||||
private int totalSuccessfulHits() => tinyTicksHit + ticksHit + fruitsHit;
|
||||
private int totalComboHits() => misses + ticksHit + fruitsHit;
|
||||
}
|
||||
}
|
||||
|
118
osu.Game/Scoring/Legacy/LegacyScoreInfo.cs
Normal file
118
osu.Game/Scoring/Legacy/LegacyScoreInfo.cs
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Scoring.Legacy
|
||||
{
|
||||
public class LegacyScoreInfo : ScoreInfo
|
||||
{
|
||||
private int countGeki;
|
||||
|
||||
public int CountGeki
|
||||
{
|
||||
get => countGeki;
|
||||
set
|
||||
{
|
||||
countGeki = value;
|
||||
|
||||
switch (Ruleset?.ID ?? RulesetID)
|
||||
{
|
||||
case 3:
|
||||
Statistics[HitResult.Perfect] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int count300;
|
||||
|
||||
public int Count300
|
||||
{
|
||||
get => count300;
|
||||
set
|
||||
{
|
||||
count300 = value;
|
||||
|
||||
switch (Ruleset?.ID ?? RulesetID)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 3:
|
||||
Statistics[HitResult.Great] = value;
|
||||
break;
|
||||
case 2:
|
||||
Statistics[HitResult.Perfect] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int countKatu;
|
||||
|
||||
public int CountKatu
|
||||
{
|
||||
get => countKatu;
|
||||
set
|
||||
{
|
||||
countKatu = value;
|
||||
|
||||
switch (Ruleset?.ID ?? RulesetID)
|
||||
{
|
||||
case 3:
|
||||
Statistics[HitResult.Good] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int count100;
|
||||
|
||||
public int Count100
|
||||
{
|
||||
get => count100;
|
||||
set
|
||||
{
|
||||
count100 = value;
|
||||
|
||||
switch (Ruleset?.ID ?? RulesetID)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
Statistics[HitResult.Good] = value;
|
||||
break;
|
||||
case 3:
|
||||
Statistics[HitResult.Ok] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int count50;
|
||||
|
||||
public int Count50
|
||||
{
|
||||
get => count50;
|
||||
set
|
||||
{
|
||||
count50 = value;
|
||||
|
||||
switch (Ruleset?.ID ?? RulesetID)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
case 3:
|
||||
Statistics[HitResult.Meh] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int CountMiss
|
||||
{
|
||||
get => Statistics[HitResult.Miss];
|
||||
set => Statistics[HitResult.Miss] = value;
|
||||
}
|
||||
}
|
||||
}
|
@ -34,7 +34,9 @@ namespace osu.Game.Scoring.Legacy
|
||||
using (SerializationReader sr = new SerializationReader(stream))
|
||||
{
|
||||
currentRuleset = GetRuleset(sr.ReadByte());
|
||||
score.ScoreInfo = new ScoreInfo { Ruleset = currentRuleset.RulesetInfo };
|
||||
var scoreInfo = new LegacyScoreInfo { Ruleset = currentRuleset.RulesetInfo };
|
||||
|
||||
scoreInfo = scoreInfo;
|
||||
|
||||
var version = sr.ReadInt32();
|
||||
|
||||
@ -43,69 +45,39 @@ namespace osu.Game.Scoring.Legacy
|
||||
throw new BeatmapNotFoundException();
|
||||
|
||||
currentBeatmap = workingBeatmap.Beatmap;
|
||||
score.ScoreInfo.Beatmap = currentBeatmap.BeatmapInfo;
|
||||
scoreInfo.Beatmap = currentBeatmap.BeatmapInfo;
|
||||
|
||||
score.ScoreInfo.User = new User { Username = sr.ReadString() };
|
||||
scoreInfo.User = new User { Username = sr.ReadString() };
|
||||
|
||||
// MD5Hash
|
||||
sr.ReadString();
|
||||
|
||||
var count300 = (int)sr.ReadUInt16();
|
||||
var count100 = (int)sr.ReadUInt16();
|
||||
var count50 = (int)sr.ReadUInt16();
|
||||
var countGeki = (int)sr.ReadUInt16();
|
||||
var countKatu = (int)sr.ReadUInt16();
|
||||
var countMiss = (int)sr.ReadUInt16();
|
||||
scoreInfo.Count300 = sr.ReadUInt16();
|
||||
scoreInfo.Count100 = sr.ReadUInt16();
|
||||
scoreInfo.Count50 = sr.ReadUInt16();
|
||||
scoreInfo.CountGeki = sr.ReadUInt16();
|
||||
scoreInfo.CountKatu = sr.ReadUInt16();
|
||||
scoreInfo.CountMiss = sr.ReadUInt16();
|
||||
|
||||
switch (currentRuleset.LegacyID)
|
||||
{
|
||||
case 0:
|
||||
score.ScoreInfo.Statistics[HitResult.Great] = count300;
|
||||
score.ScoreInfo.Statistics[HitResult.Good] = count100;
|
||||
score.ScoreInfo.Statistics[HitResult.Meh] = count50;
|
||||
score.ScoreInfo.Statistics[HitResult.Miss] = countMiss;
|
||||
break;
|
||||
case 1:
|
||||
score.ScoreInfo.Statistics[HitResult.Great] = count300;
|
||||
score.ScoreInfo.Statistics[HitResult.Good] = count100;
|
||||
score.ScoreInfo.Statistics[HitResult.Miss] = countMiss;
|
||||
break;
|
||||
case 2:
|
||||
score.ScoreInfo.Statistics[HitResult.Great] = count300;
|
||||
score.ScoreInfo.Statistics[HitResult.Good] = count100;
|
||||
score.ScoreInfo.Statistics[HitResult.Ok] = countKatu;
|
||||
score.ScoreInfo.Statistics[HitResult.Meh] = count50;
|
||||
score.ScoreInfo.Statistics[HitResult.Miss] = countMiss;
|
||||
break;
|
||||
case 3:
|
||||
score.ScoreInfo.Statistics[HitResult.Perfect] = countGeki;
|
||||
score.ScoreInfo.Statistics[HitResult.Great] = count300;
|
||||
score.ScoreInfo.Statistics[HitResult.Good] = countKatu;
|
||||
score.ScoreInfo.Statistics[HitResult.Ok] = count100;
|
||||
score.ScoreInfo.Statistics[HitResult.Meh] = count50;
|
||||
score.ScoreInfo.Statistics[HitResult.Miss] = countMiss;
|
||||
break;
|
||||
}
|
||||
|
||||
score.ScoreInfo.TotalScore = sr.ReadInt32();
|
||||
score.ScoreInfo.MaxCombo = sr.ReadUInt16();
|
||||
scoreInfo.TotalScore = sr.ReadInt32();
|
||||
scoreInfo.MaxCombo = sr.ReadUInt16();
|
||||
|
||||
/* score.Perfect = */
|
||||
sr.ReadBoolean();
|
||||
|
||||
score.ScoreInfo.Mods = currentRuleset.ConvertLegacyMods((LegacyMods)sr.ReadInt32()).ToArray();
|
||||
scoreInfo.Mods = currentRuleset.ConvertLegacyMods((LegacyMods)sr.ReadInt32()).ToArray();
|
||||
|
||||
/* score.HpGraphString = */
|
||||
sr.ReadString();
|
||||
|
||||
score.ScoreInfo.Date = sr.ReadDateTime();
|
||||
scoreInfo.Date = sr.ReadDateTime();
|
||||
|
||||
var compressedReplay = sr.ReadByteArray();
|
||||
|
||||
if (version >= 20140721)
|
||||
score.ScoreInfo.OnlineScoreID = sr.ReadInt64();
|
||||
scoreInfo.OnlineScoreID = sr.ReadInt64();
|
||||
else if (version >= 20121008)
|
||||
score.ScoreInfo.OnlineScoreID = sr.ReadInt32();
|
||||
scoreInfo.OnlineScoreID = sr.ReadInt32();
|
||||
|
||||
if (compressedReplay?.Length > 0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user