mirror of
https://github.com/ppy/osu.git
synced 2025-01-14 03:25:11 +08:00
Added BeatmapAttributesDisplay support
This commit is contained in:
parent
c61212c523
commit
1a70110a4e
@ -238,10 +238,10 @@ namespace osu.Game.Rulesets.Catch
|
||||
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 @@ namespace osu.Game.Rulesets.Catch
|
||||
|
||||
adjustedDifficulty.ApproachRate = ChangeArFromRate(ar, speedChange);
|
||||
|
||||
if (adjustedDifficulty.ApproachRate != ar) isRateAdjusted.AR = true;
|
||||
rateAdjustedInfo.AR = GetRateAdjustType(ar, adjustedDifficulty.ApproachRate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,10 +431,10 @@ namespace osu.Game.Rulesets.Mania
|
||||
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 @@ namespace osu.Game.Rulesets.Mania
|
||||
|
||||
adjustedDifficulty.OverallDifficulty = ChangeOdFromRate(od, speedChange);
|
||||
|
||||
if (adjustedDifficulty.OverallDifficulty != od) isRateAdjusted.OD = true;
|
||||
rateAdjustedInfo.OD = GetRateAdjustType(od, adjustedDifficulty.OverallDifficulty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,10 +335,10 @@ namespace osu.Game.Rulesets.Osu
|
||||
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 @@ namespace osu.Game.Rulesets.Osu
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,10 +266,10 @@ namespace osu.Game.Rulesets.Taiko
|
||||
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 @@ namespace osu.Game.Rulesets.Taiko
|
||||
|
||||
adjustedDifficulty.OverallDifficulty = ChangeOdFromRate(od, speedChange);
|
||||
|
||||
if (adjustedDifficulty.OverallDifficulty != od) isRateAdjusted.OD = true;
|
||||
rateAdjustedInfo.OD = GetRateAdjustType(od, adjustedDifficulty.OverallDifficulty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ using osu.Game.Beatmaps.Drawables;
|
||||
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 @@ namespace osu.Game.Overlays.Mods
|
||||
[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 @@ namespace osu.Game.Overlays.Mods
|
||||
updateCollapsedState();
|
||||
});
|
||||
|
||||
gameRuleset = game.Ruleset.GetBoundCopy();
|
||||
gameRuleset.BindValueChanged(_ => updateValues());
|
||||
|
||||
BeatmapInfo.BindValueChanged(_ => updateValues(), true);
|
||||
}
|
||||
|
||||
@ -243,9 +251,12 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
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;
|
||||
|
@ -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.Framework.Localisation;
|
||||
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 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
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 @@ namespace osu.Game.Overlays.Mods
|
||||
Origin = Anchor.CentreLeft;
|
||||
Anchor = Anchor.CentreLeft;
|
||||
|
||||
RateChangeType.BindValueChanged(_ => updateTextColor());
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
Origin = Anchor.CentreLeft,
|
||||
@ -45,7 +84,7 @@ namespace osu.Game.Overlays.Mods
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
text = new OsuSpriteText
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
@ -53,7 +92,7 @@ namespace osu.Game.Overlays.Mods
|
||||
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 @@ namespace osu.Game.Overlays.Mods
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -389,6 +389,21 @@ namespace osu.Game.Rulesets
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,12 +116,12 @@ namespace osu.Game.Screens.Select.Details
|
||||
{
|
||||
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 @@ namespace osu.Game.Screens.Select.Details
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user