1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-21 23:23:52 +08:00

Add LegacyScoreInfo for statistics preservation/conversion

This commit is contained in:
smoogipoo 2019-03-27 16:55:46 +09:00
parent 1a6c2022ea
commit 8fcb75809d
3 changed files with 154 additions and 59 deletions

View File

@ -9,6 +9,7 @@ using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Scoring.Legacy;
using osuTK; using osuTK;
namespace osu.Game.Rulesets.Catch.Difficulty namespace osu.Game.Rulesets.Catch.Difficulty
@ -18,11 +19,12 @@ namespace osu.Game.Rulesets.Catch.Difficulty
protected new CatchDifficultyAttributes Attributes => (CatchDifficultyAttributes)base.Attributes; protected new CatchDifficultyAttributes Attributes => (CatchDifficultyAttributes)base.Attributes;
private Mod[] mods; private Mod[] mods;
private int countGreat;
private int countGood; private int fruitsHit;
private int countKatu; private int ticksHit;
private int countMeh; private int tinyTicksHit;
private int countMiss; private int tinyTicksMissed;
private int misses;
public CatchPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) public CatchPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score)
: base(ruleset, beatmap, score) : base(ruleset, beatmap, score)
@ -32,11 +34,14 @@ namespace osu.Game.Rulesets.Catch.Difficulty
public override double Calculate(Dictionary<string, double> categoryDifficulty = null) public override double Calculate(Dictionary<string, double> categoryDifficulty = null)
{ {
mods = Score.Mods; mods = Score.Mods;
countGreat = Convert.ToInt32(Score.Statistics[HitResult.Great]);
countGood = Convert.ToInt32(Score.Statistics[HitResult.Good]); var legacyScore = Score as LegacyScoreInfo;
countKatu = Convert.ToInt32(Score.Statistics[HitResult.Ok]);
countMeh = Convert.ToInt32(Score.Statistics[HitResult.Meh]); fruitsHit = legacyScore?.Count300 ?? Score.Statistics[HitResult.Perfect];
countMiss = Convert.ToInt32(Score.Statistics[HitResult.Miss]); 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 // Don't count scores made with supposedly unranked mods
if (mods.Any(m => !m.Ranked)) if (mods.Any(m => !m.Ranked))
@ -57,7 +62,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
value *= lengthBonus; value *= lengthBonus;
// Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available // 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 // Combo scaling
float beatmapMaxCombo = Attributes.MaxCombo; 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 float accuracy() => totalHits() == 0 ? 0 : MathHelper.Clamp((float)totalSuccessfulHits() / totalHits(), 0f, 1f);
private int totalHits() => countMeh + countGood + countGreat + countMiss + countKatu; private int totalHits() => tinyTicksHit + ticksHit + fruitsHit + misses + tinyTicksMissed;
private int totalSuccessfulHits() => countMeh + countGood + countGreat; private int totalSuccessfulHits() => tinyTicksHit + ticksHit + fruitsHit;
private int totalComboHits() => countMiss + countGood + countGreat; private int totalComboHits() => misses + ticksHit + fruitsHit;
} }
} }

View 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;
}
}
}

View File

@ -34,7 +34,9 @@ namespace osu.Game.Scoring.Legacy
using (SerializationReader sr = new SerializationReader(stream)) using (SerializationReader sr = new SerializationReader(stream))
{ {
currentRuleset = GetRuleset(sr.ReadByte()); currentRuleset = GetRuleset(sr.ReadByte());
score.ScoreInfo = new ScoreInfo { Ruleset = currentRuleset.RulesetInfo }; var scoreInfo = new LegacyScoreInfo { Ruleset = currentRuleset.RulesetInfo };
scoreInfo = scoreInfo;
var version = sr.ReadInt32(); var version = sr.ReadInt32();
@ -43,69 +45,39 @@ namespace osu.Game.Scoring.Legacy
throw new BeatmapNotFoundException(); throw new BeatmapNotFoundException();
currentBeatmap = workingBeatmap.Beatmap; 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 // MD5Hash
sr.ReadString(); sr.ReadString();
var count300 = (int)sr.ReadUInt16(); scoreInfo.Count300 = sr.ReadUInt16();
var count100 = (int)sr.ReadUInt16(); scoreInfo.Count100 = sr.ReadUInt16();
var count50 = (int)sr.ReadUInt16(); scoreInfo.Count50 = sr.ReadUInt16();
var countGeki = (int)sr.ReadUInt16(); scoreInfo.CountGeki = sr.ReadUInt16();
var countKatu = (int)sr.ReadUInt16(); scoreInfo.CountKatu = sr.ReadUInt16();
var countMiss = (int)sr.ReadUInt16(); scoreInfo.CountMiss = sr.ReadUInt16();
switch (currentRuleset.LegacyID) scoreInfo.TotalScore = sr.ReadInt32();
{ scoreInfo.MaxCombo = sr.ReadUInt16();
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();
/* score.Perfect = */ /* score.Perfect = */
sr.ReadBoolean(); sr.ReadBoolean();
score.ScoreInfo.Mods = currentRuleset.ConvertLegacyMods((LegacyMods)sr.ReadInt32()).ToArray(); scoreInfo.Mods = currentRuleset.ConvertLegacyMods((LegacyMods)sr.ReadInt32()).ToArray();
/* score.HpGraphString = */ /* score.HpGraphString = */
sr.ReadString(); sr.ReadString();
score.ScoreInfo.Date = sr.ReadDateTime(); scoreInfo.Date = sr.ReadDateTime();
var compressedReplay = sr.ReadByteArray(); var compressedReplay = sr.ReadByteArray();
if (version >= 20140721) if (version >= 20140721)
score.ScoreInfo.OnlineScoreID = sr.ReadInt64(); scoreInfo.OnlineScoreID = sr.ReadInt64();
else if (version >= 20121008) else if (version >= 20121008)
score.ScoreInfo.OnlineScoreID = sr.ReadInt32(); scoreInfo.OnlineScoreID = sr.ReadInt32();
if (compressedReplay?.Length > 0) if (compressedReplay?.Length > 0)
{ {