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

turn difficulty attributes into a struct

This commit is contained in:
minisbett 2024-11-16 16:31:36 +01:00
parent e70f257947
commit e88dff0c87
No known key found for this signature in database
GPG Key ID: 2DB6D529C95A0403
25 changed files with 147 additions and 132 deletions

View File

@ -19,9 +19,9 @@ namespace osu.Game.Rulesets.EmptyFreeform
{ {
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
return new DifficultyAttributes(mods, 0); return new IDifficultyAttributes(mods, 0);
} }
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();

View File

@ -19,9 +19,9 @@ namespace osu.Game.Rulesets.Pippidon
{ {
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
return new DifficultyAttributes(mods, 0); return new IDifficultyAttributes(mods, 0);
} }
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();

View File

@ -19,9 +19,9 @@ namespace osu.Game.Rulesets.EmptyScrolling
{ {
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
return new DifficultyAttributes(mods, 0); return new IDifficultyAttributes(mods, 0);
} }
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();

View File

@ -19,9 +19,9 @@ namespace osu.Game.Rulesets.Pippidon
{ {
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
return new DifficultyAttributes(mods, 0); return new IDifficultyAttributes(mods, 0);
} }
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();

View File

@ -1,15 +1,28 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Catch.Difficulty namespace osu.Game.Rulesets.Catch.Difficulty
{ {
public class CatchDifficultyAttributes : DifficultyAttributes public struct CatchDifficultyAttributes : IDifficultyAttributes
{ {
public CatchDifficultyAttributes() { }
/// <inheritdoc/>
public Mod[] Mods { get; set; } = Array.Empty<Mod>();
/// <inheritdoc/>
public double StarRating { get; set; }
/// <inheritdoc/>
public int MaxCombo { get; set; }
/// <summary> /// <summary>
/// The perceived approach rate inclusive of rate-adjusting mods (DT/HT/etc). /// The perceived approach rate inclusive of rate-adjusting mods (DT/HT/etc).
/// </summary> /// </summary>
@ -19,22 +32,19 @@ namespace osu.Game.Rulesets.Catch.Difficulty
[JsonProperty("approach_rate")] [JsonProperty("approach_rate")]
public double ApproachRate { get; set; } public double ApproachRate { get; set; }
public override IEnumerable<(int attributeId, object value)> ToDatabaseAttributes() public IEnumerable<(int attributeId, object value)> ToDatabaseAttributes()
{ {
foreach (var v in base.ToDatabaseAttributes()) yield return (IDifficultyAttributes.ATTRIB_ID_MAX_COMBO, MaxCombo);
yield return v;
// Todo: osu!catch should not output star rating in the 'aim' attribute. // Todo: osu!catch should not output star rating in the 'aim' attribute.
yield return (ATTRIB_ID_AIM, StarRating); yield return (IDifficultyAttributes.ATTRIB_ID_AIM, StarRating);
yield return (ATTRIB_ID_APPROACH_RATE, ApproachRate); yield return (IDifficultyAttributes.ATTRIB_ID_APPROACH_RATE, ApproachRate);
} }
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo) public void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
{ {
base.FromDatabaseAttributes(values, onlineInfo); MaxCombo = (int)values[IDifficultyAttributes.ATTRIB_ID_MAX_COMBO];
StarRating = values[IDifficultyAttributes.ATTRIB_ID_AIM];
StarRating = values[ATTRIB_ID_AIM]; ApproachRate = values[IDifficultyAttributes.ATTRIB_ID_APPROACH_RATE];
ApproachRate = values[ATTRIB_ID_APPROACH_RATE];
} }
} }
} }

View File

@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
{ {
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
if (beatmap.HitObjects.Count == 0) if (beatmap.HitObjects.Count == 0)
return new CatchDifficultyAttributes { Mods = mods }; return new CatchDifficultyAttributes { Mods = mods };

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
{ {
} }
protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes) protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, IDifficultyAttributes attributes)
{ {
var catchAttributes = (CatchDifficultyAttributes)attributes; var catchAttributes = (CatchDifficultyAttributes)attributes;

View File

@ -1,15 +1,28 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Difficulty namespace osu.Game.Rulesets.Mania.Difficulty
{ {
public class ManiaDifficultyAttributes : DifficultyAttributes public struct ManiaDifficultyAttributes : IDifficultyAttributes
{ {
public ManiaDifficultyAttributes() { }
/// <inheritdoc/>
public Mod[] Mods { get; set; } = Array.Empty<Mod>();
/// <inheritdoc/>
public double StarRating { get; set; }
/// <inheritdoc/>
public int MaxCombo { get; set; }
/// <summary> /// <summary>
/// The hit window for a GREAT hit inclusive of rate-adjusting mods (DT/HT/etc). /// The hit window for a GREAT hit inclusive of rate-adjusting mods (DT/HT/etc).
/// </summary> /// </summary>
@ -19,21 +32,18 @@ namespace osu.Game.Rulesets.Mania.Difficulty
[JsonProperty("great_hit_window")] [JsonProperty("great_hit_window")]
public double GreatHitWindow { get; set; } public double GreatHitWindow { get; set; }
public override IEnumerable<(int attributeId, object value)> ToDatabaseAttributes() public IEnumerable<(int attributeId, object value)> ToDatabaseAttributes()
{ {
foreach (var v in base.ToDatabaseAttributes()) yield return (IDifficultyAttributes.ATTRIB_ID_MAX_COMBO, MaxCombo);
yield return v; yield return (IDifficultyAttributes.ATTRIB_ID_DIFFICULTY, StarRating);
yield return (IDifficultyAttributes.ATTRIB_ID_GREAT_HIT_WINDOW, GreatHitWindow);
yield return (ATTRIB_ID_DIFFICULTY, StarRating);
yield return (ATTRIB_ID_GREAT_HIT_WINDOW, GreatHitWindow);
} }
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo) public void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
{ {
base.FromDatabaseAttributes(values, onlineInfo); MaxCombo = (int)values[IDifficultyAttributes.ATTRIB_ID_MAX_COMBO];
StarRating = values[IDifficultyAttributes.ATTRIB_ID_DIFFICULTY];
StarRating = values[ATTRIB_ID_DIFFICULTY]; GreatHitWindow = values[IDifficultyAttributes.ATTRIB_ID_GREAT_HIT_WINDOW];
GreatHitWindow = values[ATTRIB_ID_GREAT_HIT_WINDOW];
} }
} }
} }

View File

@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
originalOverallDifficulty = beatmap.BeatmapInfo.Difficulty.OverallDifficulty; originalOverallDifficulty = beatmap.BeatmapInfo.Difficulty.OverallDifficulty;
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
if (beatmap.HitObjects.Count == 0) if (beatmap.HitObjects.Count == 0)
return new ManiaDifficultyAttributes { Mods = mods }; return new ManiaDifficultyAttributes { Mods = mods };

View File

@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
{ {
} }
protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes) protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, IDifficultyAttributes attributes)
{ {
var maniaAttributes = (ManiaDifficultyAttributes)attributes; var maniaAttributes = (ManiaDifficultyAttributes)attributes;

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
@ -11,8 +12,19 @@ using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Osu.Difficulty namespace osu.Game.Rulesets.Osu.Difficulty
{ {
public class OsuDifficultyAttributes : DifficultyAttributes public struct OsuDifficultyAttributes : IDifficultyAttributes
{ {
public OsuDifficultyAttributes() { }
/// <inheritdoc/>
public Mod[] Mods { get; set; } = Array.Empty<Mod>();
/// <inheritdoc/>
public double StarRating { get; set; }
/// <inheritdoc/>
public int MaxCombo { get; set; }
/// <summary> /// <summary>
/// The difficulty corresponding to the aim skill. /// The difficulty corresponding to the aim skill.
/// </summary> /// </summary>
@ -90,41 +102,38 @@ namespace osu.Game.Rulesets.Osu.Difficulty
/// </summary> /// </summary>
public int SpinnerCount { get; set; } public int SpinnerCount { get; set; }
public override IEnumerable<(int attributeId, object value)> ToDatabaseAttributes() public IEnumerable<(int attributeId, object value)> ToDatabaseAttributes()
{ {
foreach (var v in base.ToDatabaseAttributes()) yield return (IDifficultyAttributes.ATTRIB_ID_MAX_COMBO, MaxCombo);
yield return v; yield return (IDifficultyAttributes.ATTRIB_ID_AIM, AimDifficulty);
yield return (IDifficultyAttributes.ATTRIB_ID_SPEED, SpeedDifficulty);
yield return (ATTRIB_ID_AIM, AimDifficulty); yield return (IDifficultyAttributes.ATTRIB_ID_OVERALL_DIFFICULTY, OverallDifficulty);
yield return (ATTRIB_ID_SPEED, SpeedDifficulty); yield return (IDifficultyAttributes.ATTRIB_ID_APPROACH_RATE, ApproachRate);
yield return (ATTRIB_ID_OVERALL_DIFFICULTY, OverallDifficulty); yield return (IDifficultyAttributes.ATTRIB_ID_DIFFICULTY, StarRating);
yield return (ATTRIB_ID_APPROACH_RATE, ApproachRate);
yield return (ATTRIB_ID_DIFFICULTY, StarRating);
if (ShouldSerializeFlashlightDifficulty()) if (ShouldSerializeFlashlightDifficulty())
yield return (ATTRIB_ID_FLASHLIGHT, FlashlightDifficulty); yield return (IDifficultyAttributes.ATTRIB_ID_FLASHLIGHT, FlashlightDifficulty);
yield return (ATTRIB_ID_SLIDER_FACTOR, SliderFactor); yield return (IDifficultyAttributes.ATTRIB_ID_SLIDER_FACTOR, SliderFactor);
yield return (ATTRIB_ID_AIM_DIFFICULT_STRAIN_COUNT, AimDifficultStrainCount); yield return (IDifficultyAttributes.ATTRIB_ID_AIM_DIFFICULT_STRAIN_COUNT, AimDifficultStrainCount);
yield return (ATTRIB_ID_SPEED_DIFFICULT_STRAIN_COUNT, SpeedDifficultStrainCount); yield return (IDifficultyAttributes.ATTRIB_ID_SPEED_DIFFICULT_STRAIN_COUNT, SpeedDifficultStrainCount);
yield return (ATTRIB_ID_SPEED_NOTE_COUNT, SpeedNoteCount); yield return (IDifficultyAttributes.ATTRIB_ID_SPEED_NOTE_COUNT, SpeedNoteCount);
} }
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo) public void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
{ {
base.FromDatabaseAttributes(values, onlineInfo); MaxCombo = (int)values[IDifficultyAttributes.ATTRIB_ID_MAX_COMBO];
AimDifficulty = values[IDifficultyAttributes.ATTRIB_ID_AIM];
AimDifficulty = values[ATTRIB_ID_AIM]; SpeedDifficulty = values[IDifficultyAttributes.ATTRIB_ID_SPEED];
SpeedDifficulty = values[ATTRIB_ID_SPEED]; OverallDifficulty = values[IDifficultyAttributes.ATTRIB_ID_OVERALL_DIFFICULTY];
OverallDifficulty = values[ATTRIB_ID_OVERALL_DIFFICULTY]; ApproachRate = values[IDifficultyAttributes.ATTRIB_ID_APPROACH_RATE];
ApproachRate = values[ATTRIB_ID_APPROACH_RATE]; StarRating = values[IDifficultyAttributes.ATTRIB_ID_DIFFICULTY];
StarRating = values[ATTRIB_ID_DIFFICULTY]; FlashlightDifficulty = values.GetValueOrDefault(IDifficultyAttributes.ATTRIB_ID_FLASHLIGHT);
FlashlightDifficulty = values.GetValueOrDefault(ATTRIB_ID_FLASHLIGHT); SliderFactor = values[IDifficultyAttributes.ATTRIB_ID_SLIDER_FACTOR];
SliderFactor = values[ATTRIB_ID_SLIDER_FACTOR]; AimDifficultStrainCount = values[IDifficultyAttributes.ATTRIB_ID_AIM_DIFFICULT_STRAIN_COUNT];
AimDifficultStrainCount = values[ATTRIB_ID_AIM_DIFFICULT_STRAIN_COUNT]; SpeedDifficultStrainCount = values[IDifficultyAttributes.ATTRIB_ID_SPEED_DIFFICULT_STRAIN_COUNT];
SpeedDifficultStrainCount = values[ATTRIB_ID_SPEED_DIFFICULT_STRAIN_COUNT]; SpeedNoteCount = values[IDifficultyAttributes.ATTRIB_ID_SPEED_NOTE_COUNT];
SpeedNoteCount = values[ATTRIB_ID_SPEED_NOTE_COUNT];
DrainRate = onlineInfo.DrainRate; DrainRate = onlineInfo.DrainRate;
HitCircleCount = onlineInfo.CircleCount; HitCircleCount = onlineInfo.CircleCount;
SliderCount = onlineInfo.SliderCount; SliderCount = onlineInfo.SliderCount;

View File

@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
{ {
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
if (beatmap.HitObjects.Count == 0) if (beatmap.HitObjects.Count == 0)
return new OsuDifficultyAttributes { Mods = mods }; return new OsuDifficultyAttributes { Mods = mods };

View File

@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
{ {
} }
protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes) protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, IDifficultyAttributes attributes)
{ {
var osuAttributes = (OsuDifficultyAttributes)attributes; var osuAttributes = (OsuDifficultyAttributes)attributes;

View File

@ -1,15 +1,29 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Taiko.Difficulty namespace osu.Game.Rulesets.Taiko.Difficulty
{ {
public class TaikoDifficultyAttributes : DifficultyAttributes public struct TaikoDifficultyAttributes : IDifficultyAttributes
{ {
public TaikoDifficultyAttributes() { }
/// <inheritdoc/>
public Mod[] Mods { get; set; } = Array.Empty<Mod>();
/// <inheritdoc/>
public double StarRating { get; set; }
/// <inheritdoc/>
[JsonProperty("max_combo", Order = -2)]
public int MaxCombo { get; set; }
/// <summary> /// <summary>
/// The difficulty corresponding to the stamina skill. /// The difficulty corresponding to the stamina skill.
/// </summary> /// </summary>
@ -52,23 +66,20 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
[JsonProperty("ok_hit_window")] [JsonProperty("ok_hit_window")]
public double OkHitWindow { get; set; } public double OkHitWindow { get; set; }
public override IEnumerable<(int attributeId, object value)> ToDatabaseAttributes() public IEnumerable<(int attributeId, object value)> ToDatabaseAttributes()
{ {
foreach (var v in base.ToDatabaseAttributes()) yield return (IDifficultyAttributes.ATTRIB_ID_MAX_COMBO, MaxCombo);
yield return v; yield return (IDifficultyAttributes.ATTRIB_ID_DIFFICULTY, StarRating);
yield return (IDifficultyAttributes.ATTRIB_ID_GREAT_HIT_WINDOW, GreatHitWindow);
yield return (ATTRIB_ID_DIFFICULTY, StarRating); yield return (IDifficultyAttributes.ATTRIB_ID_OK_HIT_WINDOW, OkHitWindow);
yield return (ATTRIB_ID_GREAT_HIT_WINDOW, GreatHitWindow);
yield return (ATTRIB_ID_OK_HIT_WINDOW, OkHitWindow);
} }
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo) public void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
{ {
base.FromDatabaseAttributes(values, onlineInfo); MaxCombo = (int)values[IDifficultyAttributes.ATTRIB_ID_MAX_COMBO];
StarRating = values[IDifficultyAttributes.ATTRIB_ID_DIFFICULTY];
StarRating = values[ATTRIB_ID_DIFFICULTY]; GreatHitWindow = values[IDifficultyAttributes.ATTRIB_ID_GREAT_HIT_WINDOW];
GreatHitWindow = values[ATTRIB_ID_GREAT_HIT_WINDOW]; OkHitWindow = values[IDifficultyAttributes.ATTRIB_ID_OK_HIT_WINDOW];
OkHitWindow = values[ATTRIB_ID_OK_HIT_WINDOW];
} }
} }
} }

View File

@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
return difficultyHitObjects; return difficultyHitObjects;
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
if (beatmap.HitObjects.Count == 0) if (beatmap.HitObjects.Count == 0)
return new TaikoDifficultyAttributes { Mods = mods }; return new TaikoDifficultyAttributes { Mods = mods };

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
{ {
} }
protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes) protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, IDifficultyAttributes attributes)
{ {
var taikoAttributes = (TaikoDifficultyAttributes)attributes; var taikoAttributes = (TaikoDifficultyAttributes)attributes;

View File

@ -222,7 +222,7 @@ namespace osu.Game.Tests.NonVisual
protected override Mod[] DifficultyAdjustmentMods { get; } protected override Mod[] DifficultyAdjustmentMods { get; }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -172,7 +172,7 @@ namespace osu.Game.Tests.NonVisual
{ {
} }
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
=> new TestDifficultyAttributes { Objects = beatmap.HitObjects.ToArray() }; => new TestDifficultyAttributes { Objects = beatmap.HitObjects.ToArray() };
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
@ -208,7 +208,7 @@ namespace osu.Game.Tests.NonVisual
} }
} }
private class TestDifficultyAttributes : DifficultyAttributes private class TestDifficultyAttributes : IDifficultyAttributes
{ {
public HitObject[] Objects = Array.Empty<HitObject>(); public HitObject[] Objects = Array.Empty<HitObject>();
} }

View File

@ -26,13 +26,13 @@ namespace osu.Game.Beatmaps
/// Might not be available if the star difficulty is associated with a beatmap that's not locally available. /// Might not be available if the star difficulty is associated with a beatmap that's not locally available.
/// </summary> /// </summary>
[CanBeNull] [CanBeNull]
public readonly DifficultyAttributes Attributes; public readonly IDifficultyAttributes Attributes;
/// <summary> /// <summary>
/// Creates a <see cref="StarDifficulty"/> structure based on <see cref="DifficultyAttributes"/> computed /// Creates a <see cref="StarDifficulty"/> structure based on <see cref="IDifficultyAttributes"/> computed
/// by a <see cref="DifficultyCalculator"/>. /// by a <see cref="DifficultyCalculator"/>.
/// </summary> /// </summary>
public StarDifficulty([NotNull] DifficultyAttributes attributes) public StarDifficulty([NotNull] IDifficultyAttributes attributes)
{ {
Stars = double.IsFinite(attributes.StarRating) ? attributes.StarRating : 0; Stars = double.IsFinite(attributes.StarRating) ? attributes.StarRating : 0;
MaxCombo = attributes.MaxCombo; MaxCombo = attributes.MaxCombo;
@ -42,7 +42,7 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// Creates a <see cref="StarDifficulty"/> structure with a pre-populated star difficulty and max combo /// Creates a <see cref="StarDifficulty"/> structure with a pre-populated star difficulty and max combo
/// in scenarios where computing <see cref="DifficultyAttributes"/> is not feasible (i.e. when working with online sources). /// in scenarios where computing <see cref="IDifficultyAttributes"/> is not feasible (i.e. when working with online sources).
/// </summary> /// </summary>
public StarDifficulty(double starDifficulty, int maxCombo) public StarDifficulty(double starDifficulty, int maxCombo)
{ {

View File

@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Difficulty
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A structure describing the difficulty of the beatmap.</returns> /// <returns>A structure describing the difficulty of the beatmap.</returns>
public DifficultyAttributes Calculate(CancellationToken cancellationToken = default) public IDifficultyAttributes Calculate(CancellationToken cancellationToken = default)
=> Calculate(Array.Empty<Mod>(), cancellationToken); => Calculate(Array.Empty<Mod>(), cancellationToken);
/// <summary> /// <summary>
@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Difficulty
/// <param name="mods">The mods that should be applied to the beatmap.</param> /// <param name="mods">The mods that should be applied to the beatmap.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A structure describing the difficulty of the beatmap.</returns> /// <returns>A structure describing the difficulty of the beatmap.</returns>
public DifficultyAttributes Calculate([NotNull] IEnumerable<Mod> mods, CancellationToken cancellationToken = default) public IDifficultyAttributes Calculate([NotNull] IEnumerable<Mod> mods, CancellationToken cancellationToken = default)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
preProcess(mods, cancellationToken); preProcess(mods, cancellationToken);
@ -140,7 +140,7 @@ namespace osu.Game.Rulesets.Difficulty
/// This can only be used to compute difficulties for legacy mod combinations. /// This can only be used to compute difficulties for legacy mod combinations.
/// </remarks> /// </remarks>
/// <returns>A collection of structures describing the difficulty of the beatmap for each mod combination.</returns> /// <returns>A collection of structures describing the difficulty of the beatmap for each mod combination.</returns>
public IEnumerable<DifficultyAttributes> CalculateAllLegacyCombinations(CancellationToken cancellationToken = default) public IEnumerable<IDifficultyAttributes> CalculateAllLegacyCombinations(CancellationToken cancellationToken = default)
{ {
var rulesetInstance = ruleset.CreateInstance(); var rulesetInstance = ruleset.CreateInstance();
@ -263,14 +263,14 @@ namespace osu.Game.Rulesets.Difficulty
protected virtual Mod[] DifficultyAdjustmentMods => Array.Empty<Mod>(); protected virtual Mod[] DifficultyAdjustmentMods => Array.Empty<Mod>();
/// <summary> /// <summary>
/// Creates <see cref="DifficultyAttributes"/> to describe beatmap's calculated difficulty. /// Creates <see cref="IDifficultyAttributes"/> to describe beatmap's calculated difficulty.
/// </summary> /// </summary>
/// <param name="beatmap">The <see cref="IBeatmap"/> whose difficulty was calculated. /// <param name="beatmap">The <see cref="IBeatmap"/> whose difficulty was calculated.
/// This may differ from <see cref="Beatmap"/> in the case of timed calculation.</param> /// This may differ from <see cref="Beatmap"/> in the case of timed calculation.</param>
/// <param name="mods">The <see cref="Mod"/>s that difficulty was calculated with.</param> /// <param name="mods">The <see cref="Mod"/>s that difficulty was calculated with.</param>
/// <param name="skills">The skills which processed the beatmap.</param> /// <param name="skills">The skills which processed the beatmap.</param>
/// <param name="clockRate">The rate at which the gameplay clock is run at.</param> /// <param name="clockRate">The rate at which the gameplay clock is run at.</param>
protected abstract DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate); protected abstract IDifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate);
/// <summary> /// <summary>
/// Enumerates <see cref="DifficultyHitObject"/>s to be processed from <see cref="HitObject"/>s in the <see cref="IBeatmap"/>. /// Enumerates <see cref="DifficultyHitObject"/>s to be processed from <see cref="HitObject"/>s in the <see cref="IBeatmap"/>.

View File

@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -13,7 +12,7 @@ namespace osu.Game.Rulesets.Difficulty
/// Describes the difficulty of a beatmap, as output by a <see cref="DifficultyCalculator"/>. /// Describes the difficulty of a beatmap, as output by a <see cref="DifficultyCalculator"/>.
/// </summary> /// </summary>
[JsonObject(MemberSerialization.OptIn)] [JsonObject(MemberSerialization.OptIn)]
public class DifficultyAttributes public interface IDifficultyAttributes
{ {
protected const int ATTRIB_ID_AIM = 1; protected const int ATTRIB_ID_AIM = 1;
protected const int ATTRIB_ID_SPEED = 3; protected const int ATTRIB_ID_SPEED = 3;
@ -33,7 +32,7 @@ namespace osu.Game.Rulesets.Difficulty
/// <summary> /// <summary>
/// The mods which were applied to the beatmap. /// The mods which were applied to the beatmap.
/// </summary> /// </summary>
public Mod[] Mods { get; set; } = Array.Empty<Mod>(); public Mod[] Mods { get; set; }
/// <summary> /// <summary>
/// The combined star rating of all skills. /// The combined star rating of all skills.
@ -48,42 +47,18 @@ namespace osu.Game.Rulesets.Difficulty
public int MaxCombo { get; set; } public int MaxCombo { get; set; }
/// <summary> /// <summary>
/// Creates new <see cref="DifficultyAttributes"/>. /// Converts this <see cref="IDifficultyAttributes"/> to osu-web compatible database attribute mappings.
/// </summary>
public DifficultyAttributes()
{
}
/// <summary>
/// Creates new <see cref="DifficultyAttributes"/>.
/// </summary>
/// <param name="mods">The mods which were applied to the beatmap.</param>
/// <param name="starRating">The combined star rating of all skills.</param>
public DifficultyAttributes(Mod[] mods, double starRating)
{
Mods = mods;
StarRating = starRating;
}
/// <summary>
/// Converts this <see cref="DifficultyAttributes"/> to osu-web compatible database attribute mappings.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// See: osu_difficulty_attribs table. /// See: osu_difficulty_attribs table.
/// </remarks> /// </remarks>
public virtual IEnumerable<(int attributeId, object value)> ToDatabaseAttributes() public IEnumerable<(int attributeId, object value)> ToDatabaseAttributes();
{
yield return (ATTRIB_ID_MAX_COMBO, MaxCombo);
}
/// <summary> /// <summary>
/// Reads osu-web database attribute mappings into this <see cref="DifficultyAttributes"/> object. /// Reads osu-web database attribute mappings into this <see cref="IDifficultyAttributes"/> object.
/// </summary> /// </summary>
/// <param name="values">The attribute mappings.</param> /// <param name="values">The attribute mappings.</param>
/// <param name="onlineInfo">The <see cref="IBeatmapOnlineInfo"/> where more information about the beatmap may be extracted from (such as AR/CS/OD/etc).</param> /// <param name="onlineInfo">The <see cref="IBeatmapOnlineInfo"/> where more information about the beatmap may be extracted from (such as AR/CS/OD/etc).</param>
public virtual void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo) public void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo);
{
MaxCombo = (int)values[ATTRIB_ID_MAX_COMBO];
}
} }
} }

View File

@ -17,10 +17,10 @@ namespace osu.Game.Rulesets.Difficulty
Ruleset = ruleset; Ruleset = ruleset;
} }
public Task<IPerformanceAttributes> CalculateAsync(ScoreInfo score, DifficultyAttributes attributes, CancellationToken cancellationToken) public Task<IPerformanceAttributes> CalculateAsync(ScoreInfo score, IDifficultyAttributes attributes, CancellationToken cancellationToken)
=> Task.Run(() => CreatePerformanceAttributes(score, attributes), cancellationToken); => Task.Run(() => CreatePerformanceAttributes(score, attributes), cancellationToken);
public IPerformanceAttributes Calculate(ScoreInfo score, DifficultyAttributes attributes) public IPerformanceAttributes Calculate(ScoreInfo score, IDifficultyAttributes attributes)
=> CreatePerformanceAttributes(score, attributes); => CreatePerformanceAttributes(score, attributes);
public IPerformanceAttributes Calculate(ScoreInfo score, IWorkingBeatmap beatmap) public IPerformanceAttributes Calculate(ScoreInfo score, IWorkingBeatmap beatmap)
@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Difficulty
/// </summary> /// </summary>
/// <param name="score">The score to create the attributes for.</param> /// <param name="score">The score to create the attributes for.</param>
/// <param name="attributes">The difficulty attributes for the beatmap relating to the score.</param> /// <param name="attributes">The difficulty attributes for the beatmap relating to the score.</param>
protected abstract IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes); protected abstract IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, IDifficultyAttributes attributes);
} }
} }

View File

@ -8,7 +8,7 @@ using System;
namespace osu.Game.Rulesets.Difficulty namespace osu.Game.Rulesets.Difficulty
{ {
/// <summary> /// <summary>
/// Wraps a <see cref="DifficultyAttributes"/> object and adds a time value for which the attribute is valid. /// Wraps a <see cref="IDifficultyAttributes"/> object and adds a time value for which the attribute is valid.
/// Output by DifficultyCalculator.CalculateTimed methods. /// Output by DifficultyCalculator.CalculateTimed methods.
/// </summary> /// </summary>
public class TimedDifficultyAttributes : IComparable<TimedDifficultyAttributes> public class TimedDifficultyAttributes : IComparable<TimedDifficultyAttributes>
@ -21,14 +21,14 @@ namespace osu.Game.Rulesets.Difficulty
/// <summary> /// <summary>
/// The attributes. /// The attributes.
/// </summary> /// </summary>
public readonly DifficultyAttributes Attributes; public readonly IDifficultyAttributes Attributes;
/// <summary> /// <summary>
/// Creates new <see cref="TimedDifficultyAttributes"/>. /// Creates new <see cref="TimedDifficultyAttributes"/>.
/// </summary> /// </summary>
/// <param name="time">The non-clock-adjusted time value at which the attributes take effect.</param> /// <param name="time">The non-clock-adjusted time value at which the attributes take effect.</param>
/// <param name="attributes">The attributes.</param> /// <param name="attributes">The attributes.</param>
public TimedDifficultyAttributes(double time, DifficultyAttributes attributes) public TimedDifficultyAttributes(double time, IDifficultyAttributes attributes)
{ {
Time = time; Time = time;
Attributes = attributes; Attributes = attributes;

View File

@ -106,7 +106,7 @@ namespace osu.Game.Screens.Play.HUD
} }
[CanBeNull] [CanBeNull]
private DifficultyAttributes getAttributeAtTime(JudgementResult judgement) private IDifficultyAttributes getAttributeAtTime(JudgementResult judgement)
{ {
if (timedAttributes == null || timedAttributes.Count == 0) if (timedAttributes == null || timedAttributes.Count == 0)
return null; return null;