mirror of
https://github.com/ppy/osu.git
synced 2026-05-19 01:10:05 +08:00
Merge branch 'master' into maximum-statistics-2
This commit is contained in:
@@ -17,6 +17,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
[JsonProperty("accuracy")]
|
||||
public double Accuracy { get; set; }
|
||||
|
||||
[JsonProperty("effective_miss_count")]
|
||||
public double EffectiveMissCount { get; set; }
|
||||
|
||||
public override IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay()
|
||||
{
|
||||
foreach (var attribute in base.GetAttributesForDisplay())
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
private int countMeh;
|
||||
private int countMiss;
|
||||
|
||||
private double effectiveMissCount;
|
||||
|
||||
public TaikoPerformanceCalculator()
|
||||
: base(new TaikoRuleset())
|
||||
{
|
||||
@@ -35,7 +37,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
countMeh = score.Statistics.GetValueOrDefault(HitResult.Meh);
|
||||
countMiss = score.Statistics.GetValueOrDefault(HitResult.Miss);
|
||||
|
||||
double multiplier = 1.12; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things
|
||||
// The effectiveMissCount is calculated by gaining a ratio for totalSuccessfulHits and increasing the miss penalty for shorter object counts lower than 1000.
|
||||
if (totalSuccessfulHits > 0)
|
||||
effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss;
|
||||
|
||||
double multiplier = 1.13;
|
||||
|
||||
if (score.Mods.Any(m => m is ModHidden))
|
||||
multiplier *= 1.075;
|
||||
@@ -55,6 +61,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
{
|
||||
Difficulty = difficultyValue,
|
||||
Accuracy = accuracyValue,
|
||||
EffectiveMissCount = effectiveMissCount,
|
||||
Total = totalValue
|
||||
};
|
||||
}
|
||||
@@ -66,18 +73,21 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
double lengthBonus = 1 + 0.1 * Math.Min(1.0, totalHits / 1500.0);
|
||||
difficultyValue *= lengthBonus;
|
||||
|
||||
difficultyValue *= Math.Pow(0.986, countMiss);
|
||||
difficultyValue *= Math.Pow(0.986, effectiveMissCount);
|
||||
|
||||
if (score.Mods.Any(m => m is ModEasy))
|
||||
difficultyValue *= 0.980;
|
||||
difficultyValue *= 0.985;
|
||||
|
||||
if (score.Mods.Any(m => m is ModHidden))
|
||||
difficultyValue *= 1.025;
|
||||
|
||||
if (score.Mods.Any(m => m is ModFlashlight<TaikoHitObject>))
|
||||
difficultyValue *= 1.05 * lengthBonus;
|
||||
if (score.Mods.Any(m => m is ModHardRock))
|
||||
difficultyValue *= 1.050;
|
||||
|
||||
return difficultyValue * Math.Pow(score.Accuracy, 1.5);
|
||||
if (score.Mods.Any(m => m is ModFlashlight<TaikoHitObject>))
|
||||
difficultyValue *= 1.050 * lengthBonus;
|
||||
|
||||
return difficultyValue * Math.Pow(score.Accuracy, 2.0);
|
||||
}
|
||||
|
||||
private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes)
|
||||
@@ -85,18 +95,20 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
if (attributes.GreatHitWindow <= 0)
|
||||
return 0;
|
||||
|
||||
double accuracyValue = Math.Pow(140.0 / attributes.GreatHitWindow, 1.1) * Math.Pow(score.Accuracy, 12.0) * 27;
|
||||
double accuracyValue = Math.Pow(60.0 / attributes.GreatHitWindow, 1.1) * Math.Pow(score.Accuracy, 8.0) * Math.Pow(attributes.StarRating, 0.4) * 27.0;
|
||||
|
||||
double lengthBonus = Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3));
|
||||
accuracyValue *= lengthBonus;
|
||||
|
||||
// Slight HDFL Bonus for accuracy.
|
||||
// Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values
|
||||
if (score.Mods.Any(m => m is ModFlashlight<TaikoHitObject>) && score.Mods.Any(m => m is ModHidden))
|
||||
accuracyValue *= 1.10 * lengthBonus;
|
||||
accuracyValue *= Math.Max(1.050, 1.075 * lengthBonus);
|
||||
|
||||
return accuracyValue;
|
||||
}
|
||||
|
||||
private int totalHits => countGreat + countOk + countMeh + countMiss;
|
||||
|
||||
private int totalSuccessfulHits => countGreat + countOk + countMeh;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,8 +244,12 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
const int total_set_count = 200;
|
||||
|
||||
for (int i = 0; i < total_set_count; i++)
|
||||
sets.Add(TestResources.CreateTestBeatmapSetInfo());
|
||||
AddStep("Populuate beatmap sets", () =>
|
||||
{
|
||||
sets.Clear();
|
||||
for (int i = 0; i < total_set_count; i++)
|
||||
sets.Add(TestResources.CreateTestBeatmapSetInfo());
|
||||
});
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
@@ -275,8 +279,12 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
const int total_set_count = 20;
|
||||
|
||||
for (int i = 0; i < total_set_count; i++)
|
||||
sets.Add(TestResources.CreateTestBeatmapSetInfo(3));
|
||||
AddStep("Populuate beatmap sets", () =>
|
||||
{
|
||||
sets.Clear();
|
||||
for (int i = 0; i < total_set_count; i++)
|
||||
sets.Add(TestResources.CreateTestBeatmapSetInfo(3));
|
||||
});
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
@@ -493,18 +501,23 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
const string zzz_string = "zzzzz";
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
AddStep("Populuate beatmap sets", () =>
|
||||
{
|
||||
var set = TestResources.CreateTestBeatmapSetInfo();
|
||||
sets.Clear();
|
||||
|
||||
if (i == 4)
|
||||
set.Beatmaps.ForEach(b => b.Metadata.Artist = zzz_string);
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
var set = TestResources.CreateTestBeatmapSetInfo();
|
||||
|
||||
if (i == 16)
|
||||
set.Beatmaps.ForEach(b => b.Metadata.Author.Username = zzz_string);
|
||||
if (i == 4)
|
||||
set.Beatmaps.ForEach(b => b.Metadata.Artist = zzz_string);
|
||||
|
||||
sets.Add(set);
|
||||
}
|
||||
if (i == 16)
|
||||
set.Beatmaps.ForEach(b => b.Metadata.Author.Username = zzz_string);
|
||||
|
||||
sets.Add(set);
|
||||
}
|
||||
});
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
@@ -521,21 +534,27 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
public void TestSortingStability()
|
||||
{
|
||||
var sets = new List<BeatmapSetInfo>();
|
||||
int idOffset = 0;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
AddStep("Populuate beatmap sets", () =>
|
||||
{
|
||||
var set = TestResources.CreateTestBeatmapSetInfo();
|
||||
sets.Clear();
|
||||
|
||||
// only need to set the first as they are a shared reference.
|
||||
var beatmap = set.Beatmaps.First();
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var set = TestResources.CreateTestBeatmapSetInfo();
|
||||
|
||||
beatmap.Metadata.Artist = $"artist {i / 2}";
|
||||
beatmap.Metadata.Title = $"title {9 - i}";
|
||||
// only need to set the first as they are a shared reference.
|
||||
var beatmap = set.Beatmaps.First();
|
||||
|
||||
sets.Add(set);
|
||||
}
|
||||
beatmap.Metadata.Artist = $"artist {i / 2}";
|
||||
beatmap.Metadata.Title = $"title {9 - i}";
|
||||
|
||||
int idOffset = sets.First().OnlineID;
|
||||
sets.Add(set);
|
||||
}
|
||||
|
||||
idOffset = sets.First().OnlineID;
|
||||
});
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
@@ -556,26 +575,32 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
public void TestSortingStabilityWithNewItems()
|
||||
{
|
||||
List<BeatmapSetInfo> sets = new List<BeatmapSetInfo>();
|
||||
int idOffset = 0;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
AddStep("Populuate beatmap sets", () =>
|
||||
{
|
||||
var set = TestResources.CreateTestBeatmapSetInfo(3);
|
||||
sets.Clear();
|
||||
|
||||
// only need to set the first as they are a shared reference.
|
||||
var beatmap = set.Beatmaps.First();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var set = TestResources.CreateTestBeatmapSetInfo(3);
|
||||
|
||||
beatmap.Metadata.Artist = "same artist";
|
||||
beatmap.Metadata.Title = "same title";
|
||||
// only need to set the first as they are a shared reference.
|
||||
var beatmap = set.Beatmaps.First();
|
||||
|
||||
sets.Add(set);
|
||||
}
|
||||
beatmap.Metadata.Artist = "same artist";
|
||||
beatmap.Metadata.Title = "same title";
|
||||
|
||||
int idOffset = sets.First().OnlineID;
|
||||
sets.Add(set);
|
||||
}
|
||||
|
||||
idOffset = sets.First().OnlineID;
|
||||
});
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false));
|
||||
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == idOffset + index).All(b => b));
|
||||
assertOriginalOrderMaintained();
|
||||
|
||||
AddStep("Add new item", () =>
|
||||
{
|
||||
@@ -590,10 +615,16 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
carousel.UpdateBeatmapSet(set);
|
||||
});
|
||||
|
||||
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == idOffset + index).All(b => b));
|
||||
assertOriginalOrderMaintained();
|
||||
|
||||
AddStep("Sort by title", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false));
|
||||
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == idOffset + index).All(b => b));
|
||||
assertOriginalOrderMaintained();
|
||||
|
||||
void assertOriginalOrderMaintained()
|
||||
{
|
||||
AddAssert("Items remain in original order",
|
||||
() => carousel.BeatmapSets.Select(s => s.OnlineID), () => Is.EqualTo(carousel.BeatmapSets.Select((set, index) => idOffset + index)));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -601,13 +632,18 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
List<BeatmapSetInfo> sets = new List<BeatmapSetInfo>();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
AddStep("Populuate beatmap sets", () =>
|
||||
{
|
||||
var set = TestResources.CreateTestBeatmapSetInfo(3);
|
||||
set.Beatmaps[0].StarRating = 3 - i;
|
||||
set.Beatmaps[2].StarRating = 6 + i;
|
||||
sets.Add(set);
|
||||
}
|
||||
sets.Clear();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var set = TestResources.CreateTestBeatmapSetInfo(3);
|
||||
set.Beatmaps[0].StarRating = 3 - i;
|
||||
set.Beatmaps[2].StarRating = 6 + i;
|
||||
sets.Add(set);
|
||||
}
|
||||
});
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
@@ -759,8 +795,13 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
List<BeatmapSetInfo> manySets = new List<BeatmapSetInfo>();
|
||||
|
||||
for (int i = 1; i <= 50; i++)
|
||||
manySets.Add(TestResources.CreateTestBeatmapSetInfo(3));
|
||||
AddStep("Populuate beatmap sets", () =>
|
||||
{
|
||||
manySets.Clear();
|
||||
|
||||
for (int i = 1; i <= 50; i++)
|
||||
manySets.Add(TestResources.CreateTestBeatmapSetInfo(3));
|
||||
});
|
||||
|
||||
loadBeatmaps(manySets);
|
||||
|
||||
@@ -791,6 +832,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddStep("populate maps", () =>
|
||||
{
|
||||
manySets.Clear();
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
manySets.Add(TestResources.CreateTestBeatmapSetInfo(3, new[]
|
||||
|
||||
Reference in New Issue
Block a user