Added BeatmapAttributesDisplay support

This commit is contained in:
Givikap120 2023-09-12 16:44:44 +03:00
parent c61212c523
commit 1a70110a4e
8 changed files with 89 additions and 25 deletions

View File

@ -238,10 +238,10 @@ public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatm
public float ArFromPreempt(double preempt) => (float)(preempt > 1200 ? ((1800 - preempt) / 120) : ((1200 - preempt) / 150)) + 5;
public float ChangeArFromRate(float AR, double rate) => ArFromPreempt(PreemptFromAr(AR) / rate);
public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (bool AR, bool OD) isRateAdjusted)
public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (RateAdjustType AR, RateAdjustType OD) rateAdjustedInfo)
{
BeatmapDifficulty? adjustedDifficulty = null;
isRateAdjusted = (false, false);
rateAdjustedInfo = (RateAdjustType.NotChanged, RateAdjustType.NotChanged);
if (mods.Any(m => m is IApplicableToDifficulty))
{
@ -264,7 +264,7 @@ public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo
adjustedDifficulty.ApproachRate = ChangeArFromRate(ar, speedChange);
if (adjustedDifficulty.ApproachRate != ar) isRateAdjusted.AR = true;
rateAdjustedInfo.AR = GetRateAdjustType(ar, adjustedDifficulty.ApproachRate);
}
}

View File

@ -431,10 +431,10 @@ public override IRulesetFilterCriteria CreateRulesetFilterCriteria()
public double HitwindowFromOd(float OD) => 64.0 - 3 * OD;
public float OdFromHitwindow(double hitwindow300) => (float)(64.0 - hitwindow300) / 3;
public float ChangeOdFromRate(float OD, double rate) => OdFromHitwindow(HitwindowFromOd(OD) / rate);
public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (bool AR, bool OD) isRateAdjusted)
public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (RateAdjustType AR, RateAdjustType OD) rateAdjustedInfo)
{
BeatmapDifficulty? adjustedDifficulty = null;
isRateAdjusted = (false, false);
rateAdjustedInfo = (RateAdjustType.NotChanged, RateAdjustType.NotChanged);
if (mods.Any(m => m is IApplicableToDifficulty))
{
@ -456,7 +456,7 @@ public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo
adjustedDifficulty.OverallDifficulty = ChangeOdFromRate(od, speedChange);
if (adjustedDifficulty.OverallDifficulty != od) isRateAdjusted.OD = true;
rateAdjustedInfo.OD = GetRateAdjustType(od, adjustedDifficulty.OverallDifficulty);
}
}

View File

@ -335,10 +335,10 @@ public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatm
public float OdFromHitwindow(double hitwindow300) => (float)(80.0 - hitwindow300) / 6;
public float ChangeArFromRate(float AR, double rate) => ArFromPreempt(PreemptFromAr(AR) / rate);
public float ChangeOdFromRate(float OD, double rate) => OdFromHitwindow(HitwindowFromOd(OD) / rate);
public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (bool AR, bool OD) isRateAdjusted)
public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (RateAdjustType AR, RateAdjustType OD) rateAdjustedInfo)
{
BeatmapDifficulty? adjustedDifficulty = null;
isRateAdjusted = (false, false);
rateAdjustedInfo = (RateAdjustType.NotChanged, RateAdjustType.NotChanged);
if (mods.Any(m => m is IApplicableToDifficulty))
{
@ -362,8 +362,8 @@ public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo
adjustedDifficulty.ApproachRate = ChangeArFromRate(ar, speedChange);
adjustedDifficulty.OverallDifficulty = ChangeOdFromRate(od, speedChange);
if (adjustedDifficulty.ApproachRate != ar) isRateAdjusted.AR = true;
if (adjustedDifficulty.OverallDifficulty != od) isRateAdjusted.OD = true;
rateAdjustedInfo.AR = GetRateAdjustType(ar, adjustedDifficulty.ApproachRate);
rateAdjustedInfo.OD = GetRateAdjustType(od, adjustedDifficulty.OverallDifficulty);
}
}

View File

@ -266,10 +266,10 @@ public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatm
public double HitwindowFromOd(float OD) => 35.0 - 15.0 * (OD - 5) / 5;
public float OdFromHitwindow(double hitwindow300) => (float)(5 * (35 - hitwindow300) / 15 + 5);
public float ChangeOdFromRate(float OD, double rate) => OdFromHitwindow(HitwindowFromOd(OD) / rate);
public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (bool AR, bool OD) isRateAdjusted)
public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (RateAdjustType AR, RateAdjustType OD) rateAdjustedInfo)
{
BeatmapDifficulty? adjustedDifficulty = null;
isRateAdjusted = (false, false);
rateAdjustedInfo = (RateAdjustType.NotChanged, RateAdjustType.NotChanged);
if (mods.Any(m => m is IApplicableToDifficulty))
{
@ -291,7 +291,7 @@ public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo
adjustedDifficulty.OverallDifficulty = ChangeOdFromRate(od, speedChange);
if (adjustedDifficulty.OverallDifficulty != od) isRateAdjusted.OD = true;
rateAdjustedInfo.OD = GetRateAdjustType(od, adjustedDifficulty.OverallDifficulty);
}
}

View File

@ -16,6 +16,7 @@
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osuTK;
using osuTK.Graphics;
@ -63,6 +64,10 @@ public partial class BeatmapAttributesDisplay : CompositeDrawable
[Resolved]
private BeatmapDifficultyCache difficultyCache { get; set; } = null!;
[Resolved]
private OsuGameBase game { get; set; } = null!;
private IBindable<RulesetInfo> gameRuleset = null!;
private CancellationTokenSource? cancellationSource;
private IBindable<StarDifficulty?> starDifficulty = null!;
@ -195,6 +200,9 @@ protected override void LoadComplete()
updateCollapsedState();
});
gameRuleset = game.Ruleset.GetBoundCopy();
gameRuleset.BindValueChanged(_ => updateValues());
BeatmapInfo.BindValueChanged(_ => updateValues(), true);
}
@ -243,9 +251,12 @@ private void updateValues() => Scheduler.AddOnce(() =>
bpmDisplay.Current.Value = BeatmapInfo.Value.BPM * rate;
BeatmapDifficulty adjustedDifficulty = new BeatmapDifficulty(BeatmapInfo.Value.Difficulty);
foreach (var mod in mods.Value.OfType<IApplicableToDifficulty>())
mod.ApplyToDifficulty(adjustedDifficulty);
(Ruleset.RateAdjustType AR, Ruleset.RateAdjustType OD) rateAdjustType = (Ruleset.RateAdjustType.NotChanged, Ruleset.RateAdjustType.NotChanged);
Ruleset ruleset = gameRuleset.Value.CreateInstance();
BeatmapDifficulty adjustedDifficulty = ruleset.GetEffectiveDifficulty(BeatmapInfo.Value.Difficulty, mods.Value, ref rateAdjustType);
approachRateDisplay.RateChangeType.Value = rateAdjustType.AR;
overallDifficultyDisplay.RateChangeType.Value = rateAdjustType.OD;
circleSizeDisplay.Current.Value = adjustedDifficulty.CircleSize;
drainRateDisplay.Current.Value = adjustedDifficulty.DrainRate;

View File

@ -1,6 +1,8 @@
// 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 System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
@ -10,6 +12,9 @@
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osuTK.Graphics;
namespace osu.Game.Overlays.Mods
{
@ -23,11 +28,43 @@ public Bindable<double> Current
private readonly BindableWithCurrent<double> current = new BindableWithCurrent<double>();
public Bindable<Ruleset.RateAdjustType> RateChangeType = new Bindable<Ruleset.RateAdjustType>(Ruleset.RateAdjustType.NotChanged);
/// <summary>
/// Text to display in the top area of the display.
/// </summary>
public LocalisableString Label { get; protected set; }
private EffectCounter counter;
private OsuSpriteText text;
[Resolved]
private OsuColour colours { get; set; } = null!;
private void updateTextColor()
{
Color4 newColor;
switch (RateChangeType.Value)
{
case Ruleset.RateAdjustType.NotChanged:
newColor = Color4.White;
break;
case Ruleset.RateAdjustType.DifficultyReduction:
newColor = colours.ForModType(ModType.DifficultyReduction);
break;
case Ruleset.RateAdjustType.DifficultyIncrease:
newColor = colours.ForModType(ModType.DifficultyIncrease);
break;
default:
throw new ArgumentOutOfRangeException(nameof(RateChangeType.Value));
}
text.Colour = newColor;
counter.Colour = newColor;
}
public VerticalAttributeDisplay(LocalisableString label)
{
Label = label;
@ -37,6 +74,8 @@ public VerticalAttributeDisplay(LocalisableString label)
Origin = Anchor.CentreLeft;
Anchor = Anchor.CentreLeft;
RateChangeType.BindValueChanged(_ => updateTextColor());
InternalChild = new FillFlowContainer
{
Origin = Anchor.CentreLeft,
@ -45,7 +84,7 @@ public VerticalAttributeDisplay(LocalisableString label)
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new OsuSpriteText
text = new OsuSpriteText
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
@ -53,7 +92,7 @@ public VerticalAttributeDisplay(LocalisableString label)
Margin = new MarginPadding { Horizontal = 15 }, // to reserve space for 0.XX value
Font = OsuFont.Default.With(size: 20, weight: FontWeight.Bold)
},
new EffectCounter
counter = new EffectCounter
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
@ -62,12 +101,11 @@ public VerticalAttributeDisplay(LocalisableString label)
}
};
}
private partial class EffectCounter : RollingCounter<double>
{
protected override double RollingDuration => 500;
protected override LocalisableString FormatCount(double count) => count.ToLocalisableString("0.0");
protected override LocalisableString FormatCount(double count) => count.ToLocalisableString("0.0#");
protected override OsuSpriteText CreateSpriteText() => new OsuSpriteText
{

View File

@ -389,6 +389,21 @@ protected Ruleset()
/// Can be overridden to alter the difficulty section to the editor beatmap setup screen.
/// </summary>
public virtual DifficultySection? CreateEditorDifficultySection() => null;
public virtual BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (bool AR, bool OD) isRateAdjusted) => (BeatmapDifficulty)baseDifficulty;
public virtual BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList<Mod> mods, ref (RateAdjustType AR, RateAdjustType OD) rateAdjustedInfo) => (BeatmapDifficulty)baseDifficulty;
public enum RateAdjustType
{
NotChanged,
DifficultyReduction,
DifficultyIncrease
}
protected RateAdjustType GetRateAdjustType(float baseValue, float adjustedValue)
{
if (adjustedValue > baseValue)
return RateAdjustType.DifficultyIncrease;
if (adjustedValue < baseValue)
return RateAdjustType.DifficultyReduction;
return RateAdjustType.NotChanged;
}
}
}

View File

@ -116,12 +116,12 @@ private void updateStatistics()
{
IBeatmapDifficultyInfo baseDifficulty = BeatmapInfo?.Difficulty;
BeatmapDifficulty adjustedDifficulty = null;
(bool AR, bool OD) isRateAdjusted = (false, false);
(Ruleset.RateAdjustType AR, Ruleset.RateAdjustType OD) rateAdjustInfo = (Ruleset.RateAdjustType.NotChanged, Ruleset.RateAdjustType.NotChanged);
if (baseDifficulty != null)
{
Ruleset ruleset = gameRuleset.Value.CreateInstance();
adjustedDifficulty = ruleset.GetEffectiveDifficulty(baseDifficulty, mods.Value, ref isRateAdjusted);
adjustedDifficulty = ruleset.GetEffectiveDifficulty(baseDifficulty, mods.Value, ref rateAdjustInfo);
}
switch (BeatmapInfo?.Ruleset.OnlineID)
@ -140,8 +140,8 @@ private void updateStatistics()
}
HpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate, false);
Accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty, isRateAdjusted.OD);
ApproachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate, isRateAdjusted.AR);
Accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty, rateAdjustInfo.OD != Ruleset.RateAdjustType.NotChanged);
ApproachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate, rateAdjustInfo.OD != Ruleset.RateAdjustType.NotChanged);
updateStarDifficulty();
}