Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to highlight Hard Beats #467

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions osu.Game.Rulesets.Tau.Tests/Objects/TestSceneHardBeat.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Tau.Configuration;
using osu.Game.Rulesets.Tau.Objects;
using osu.Game.Rulesets.Tau.Objects.Drawables;
using osu.Game.Rulesets.Tau.UI;
Expand All @@ -15,16 +19,39 @@ public partial class TestSceneHardBeat : TauTestScene
{
private int depthIndex;

public TestSceneHardBeat()
private TauPlayfieldAdjustmentContainer container;
private BindableBool highlightHardNotes = new BindableBool();

[Test]
public void TestHardBeat()
{
TauPlayfieldAdjustmentContainer container;
Add(container = new TauPlayfieldAdjustmentContainer());
AddStep("clear screen", Clear);
AddStep("add container", () => Add(container = new TauPlayfieldAdjustmentContainer()));

AddStep("Highlighting disabled", () => highlightHardNotes.Value = false);
AddStep("Miss single", () => container.Child = testSingle());
AddStep("Hit single", () => container.Child = testSingle(true));
AddUntilStep("Wait for object despawn", () => !Children.Any(h => h is DrawableHardBeat { AllJudged: false }));
}

[Test]
public void TestHighlightedHardBeat()
{
AddStep("clear screen", Clear);
AddStep("add container", () => Add(container = new TauPlayfieldAdjustmentContainer()));

AddStep("Highlighting enabled", () => highlightHardNotes.Value = true);
AddStep("Miss single highlighted", () => container.Child = testSingle());
AddStep("Hit single highlighted", () => container.Child = testSingle(true));
AddUntilStep("Wait for object despawn", () => !Children.Any(h => h is DrawableHardBeat { AllJudged: false }));
}

[BackgroundDependencyLoader]
private void load() {
var config = (TauRulesetConfigManager)RulesetConfigs.GetConfigFor(Ruleset.Value.CreateInstance()).AsNonNull();
config.BindWith(TauRulesetSettings.HighlightHardBeats, highlightHardNotes);
}

private Drawable testSingle(bool auto = false)
{
var circle = new HardBeat
Expand Down
30 changes: 27 additions & 3 deletions osu.Game.Rulesets.Tau.Tests/Objects/TestSceneSliderHardBeat.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Tau.Configuration;
using osu.Game.Rulesets.Tau.Objects;
using osu.Game.Rulesets.Tau.Objects.Drawables;
using osu.Game.Rulesets.Tau.UI;
Expand All @@ -17,16 +21,36 @@ public partial class TestSceneSliderHardBeat : TauTestScene
private int depthIndex;

private TauPlayfieldAdjustmentContainer container;
private BindableBool highlightHardNotes = new BindableBool();

[BackgroundDependencyLoader]
private void load() {
var config = (TauRulesetConfigManager)RulesetConfigs.GetConfigFor(Ruleset.Value.CreateInstance()).AsNonNull();
config.BindWith(TauRulesetSettings.HighlightHardBeats, highlightHardNotes);
}

[Test]
public void TestSingleSlider()
{
AddStep("clear screen", Clear);
AddStep("add container", () => Add(container = new TauPlayfieldAdjustmentContainer()));
AddStep("highlighting disabled", () => highlightHardNotes.Value = false);

AddStep("Miss Single", () => container.Add(testSingle()));
AddStep("Hit Single", () => container.Add(testSingle(true)));
AddUntilStep("Wait for object despawn", () => !Children.Any(h => h is DrawableSlider { AllJudged: false }));
AddUntilStep("Wait for object despawn", () => !container.Any(h => h is DrawableSlider { AllJudged: false }));
}

[Test]
public void TestHighlightedSingleSlider()
{
AddStep("clear screen", Clear);
AddStep("add container", () => Add(container = new TauPlayfieldAdjustmentContainer()));
AddStep("highlighting enabled", () => highlightHardNotes.Value = true);

AddStep("Miss single highlighted", () => container.Add(testSingle()));
AddStep("Hit single highlighted", () => container.Add(testSingle(true)));
AddUntilStep("Wait for object despawn", () => !container.Any(h => h is DrawableSlider { AllJudged: false }));
}

[Test]
Expand All @@ -35,8 +59,8 @@ public void TestSliderPerformance()
AddStep("clear screen", Clear);
AddStep("add container", () => Add(container = new TauPlayfieldAdjustmentContainer()));

AddStep("Miss Single", () => container.AddRange(testMultiple(100)));
AddStep("Hit Single", () => container.AddRange(testMultiple(100, true)));
AddStep("Miss many", () => container.AddRange(testMultiple(100)));
AddStep("Hit many", () => container.AddRange(testMultiple(100, true)));
}

private IEnumerable<Drawable> testMultiple(int count, bool auto = false)
Expand Down
41 changes: 35 additions & 6 deletions osu.Game.Rulesets.Tau.Tests/Objects/TestSceneStrictHardBeat.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Tau.Configuration;
using osu.Game.Rulesets.Tau.Objects;
using osu.Game.Rulesets.Tau.Objects.Drawables;
using osu.Game.Rulesets.Tau.UI;
Expand All @@ -15,16 +19,41 @@ public partial class TestSceneStrictHardBeat : TauTestScene
{
private int depthIndex;

public TestSceneStrictHardBeat()
private TauPlayfieldAdjustmentContainer container;
private BindableBool highlightHardNotes = new BindableBool();

[BackgroundDependencyLoader]
private void load() {
var config = (TauRulesetConfigManager)RulesetConfigs.GetConfigFor(Ruleset.Value.CreateInstance()).AsNonNull();
config.BindWith(TauRulesetSettings.HighlightHardBeats, highlightHardNotes);
}

[Test]
public void TestStrictHardBeat()
{
AddStep("clear screen", Clear);
AddStep("add container", () => Add(container = new TauPlayfieldAdjustmentContainer()));
AddStep("highlighting disabled", () => highlightHardNotes.Value = false);

AddStep("Miss Single", () => container.Add(testSingle()));
AddStep("Hit Single", () => container.Add(testSingle(true)));
AddStep("Miss Stream", () => Add(testStream()));
AddStep("Hit Stream", () => Add(testStream(true)));
AddUntilStep("Wait for object despawn", () => !container.Any(h => h is DrawableTauHitObject<StrictHardBeat> { AllJudged: false }));
}

[Test]
public void TestHighlightedStrictHardBeat()
{
TauPlayfieldAdjustmentContainer container;
Add(container = new TauPlayfieldAdjustmentContainer());
AddStep("clear screen", Clear);
AddStep("add container", () => Add(container = new TauPlayfieldAdjustmentContainer()));
AddStep("highlighting enabled", () => highlightHardNotes.Value = true);

AddStep("Miss Single", () => container.Child = testSingle());
AddStep("Hit Single", () => container.Child = testSingle(true));
AddStep("Miss Single", () => container.Add(testSingle()));
AddStep("Hit Single", () => container.Add(testSingle(true)));
AddStep("Miss Stream", () => Add(testStream()));
AddStep("Hit Stream", () => Add(testStream(true)));
AddUntilStep("Wait for object despawn", () => !Children.Any(h => h is DrawableTauHitObject<StrictHardBeat> { AllJudged: false }));
AddUntilStep("Wait for object despawn", () => !container.Any(h => h is DrawableTauHitObject<StrictHardBeat> { AllJudged: false }));
}

private Drawable testSingle(bool auto = false, double timeOffset = 0, float angle = 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ protected override void InitialiseDefaults()
SetDefault(TauRulesetSettings.ShowVisualizer, true);
SetDefault(TauRulesetSettings.ShowSliderEffects, true);
SetDefault(TauRulesetSettings.HitLighting, false);
SetDefault(TauRulesetSettings.HighlightHardBeats, false);
SetDefault(TauRulesetSettings.KiaiType, KiaiType.Turbulence);
SetDefault(TauRulesetSettings.PlayfieldDim, 0.7f, 0, 1, 0.01f);
SetDefault(TauRulesetSettings.NotesSize, 16f, 10, 25, 1f);
Expand All @@ -30,6 +31,7 @@ public enum TauRulesetSettings
ShowVisualizer,
ShowSliderEffects, // There's no real reason to have a toggle for showing Kiai effects, as that's already handled under KiaiType
HitLighting,
HighlightHardBeats,
KiaiType,
PlayfieldDim,
NotesSize,
Expand Down
5 changes: 5 additions & 0 deletions osu.Game.Rulesets.Tau/Localisation/SettingStrings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public static class SettingStrings
/// </summary>
public static LocalisableString HitLighting => new TranslatableString(getKey(@"hit_lighting"), @"Hit Lighting");

/// <summary>
/// "Highlight Hard Beats"
/// </summary>
public static LocalisableString HighlightHardBeats = new TranslatableString(getKey(@"highlight_hard_beats"), @"Highlight Hard Beats");
Snootiful marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// "Kiai Type"
/// </summary>
Expand Down
19 changes: 17 additions & 2 deletions osu.Game.Rulesets.Tau/Objects/Drawables/DrawableSlider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Rendering;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Textures;
using osu.Framework.Platform;
using osu.Framework.Utils;
using osu.Game.Audio;
Expand All @@ -16,6 +17,7 @@
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Tau.Configuration;
using osu.Game.Rulesets.Tau.Judgements;
using osu.Game.Rulesets.Tau.UI;
using osu.Game.Skinning;
Expand All @@ -28,6 +30,7 @@ public partial class DrawableSlider : DrawableAngledTauHitObject<Slider>
public Drawable SliderHead => headContainer.Child;

private readonly BindableFloat size = new(16f);
public BindableBool HighlightHardBeats = new(false);

public float PathDistance = TauPlayfield.BASE_SIZE.X / 2;

Expand All @@ -49,6 +52,9 @@ public partial class DrawableSlider : DrawableAngledTauHitObject<Slider>

private bool inversed;

private Texture pathTexture;
private Texture pathTextureHighlighted;

public DrawableSlider()
: this(null)
{
Expand Down Expand Up @@ -141,13 +147,20 @@ protected override void ClearNestedHitObjects()
private float convertNoteSizeToSliderSize(float beatSize)
=> Interpolation.ValueAt(beatSize, 2f, 7f, 10f, 25f);

private Color4 convertHighlightSettingToColor(bool highlightHardBeats)
=> highlightHardBeats && HitObject.IsHard ? Color4.Orange : Color4.White;

[BackgroundDependencyLoader]
private void load(IRenderer renderer, GameHost host)
private void load(IRenderer renderer, GameHost host, TauRulesetConfigManager config)
{
config.BindWith(TauRulesetSettings.HighlightHardBeats, HighlightHardBeats);

NoteSize.BindValueChanged(value => path.PathRadius = convertNoteSizeToSliderSize(value.NewValue), true);
// HighlightHardBeats.BindValueChanged(value => updatePathTexture(value.NewValue, renderer));

host.DrawThread.Scheduler.AddDelayed(() => drawCache.Invalidate(), 0, true);
path.Texture = properties.SliderTexture ??= generateSmoothPathTexture(renderer, path.PathRadius, _ => Color4.White);
pathTexture = generateSmoothPathTexture(renderer, path.PathRadius, _ => Color4.White);
pathTextureHighlighted = generateSmoothPathTexture(renderer, path.PathRadius, _ => Color4.Orange);
Snootiful marked this conversation as resolved.
Show resolved Hide resolved
}

[Resolved]
Expand All @@ -159,6 +172,7 @@ protected override void OnApply()
{
base.OnApply();
path.FadeColour = colour.ForHitResult(HitResult.Great);
HighlightHardBeats.BindValueChanged(value => path.Texture = value.NewValue && HitObject.IsHard ? pathTextureHighlighted : pathTexture, true);
Snootiful marked this conversation as resolved.
Show resolved Hide resolved
Snootiful marked this conversation as resolved.
Show resolved Hide resolved

totalTimeHeld = 0;

Expand All @@ -176,6 +190,7 @@ protected override void OnFree()
base.OnFree();
trackingCheckpoints.Clear();
slidingSample?.ClearSamples();
HighlightHardBeats.UnbindEvents();
Snootiful marked this conversation as resolved.
Show resolved Hide resolved
}

protected override void LoadSamples()
Expand Down
14 changes: 12 additions & 2 deletions osu.Game.Rulesets.Tau/Objects/Drawables/Pieces/HardBeatPiece.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
using osu.Framework.Bindables;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Utils;
using osu.Game.Rulesets.Tau.Configuration;
using osuTK.Graphics;

namespace osu.Game.Rulesets.Tau.Objects.Drawables.Pieces
{
public partial class HardBeatPiece : CircularContainer
{
public BindableFloat NoteSize = new(16f);
public BindableBool HighlightHardBeats = new(false);

public HardBeatPiece()
{
Masking = true;
BorderThickness = 5;
BorderColour = Color4.White;
BorderColour = HighlightHardBeats.Value ? Color4.Orange : Color4.White;
Snootiful marked this conversation as resolved.
Show resolved Hide resolved
RelativeSizeAxes = Axes.Both;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Expand All @@ -30,6 +33,13 @@ public HardBeatPiece()
};

NoteSize.BindValueChanged(value => BorderThickness = convertNoteSizeToThickness(value.NewValue));
HighlightHardBeats.BindValueChanged(value => BorderColour = value.NewValue ? Color4.Orange : Color4.White);
}

[BackgroundDependencyLoader]
private void load(TauRulesetConfigManager config)
Snootiful marked this conversation as resolved.
Show resolved Hide resolved
{
config?.BindWith(TauRulesetSettings.HighlightHardBeats, HighlightHardBeats);
}

private float convertNoteSizeToThickness(float noteSize)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Utils;
using osu.Game.Rulesets.Tau.Configuration;
using osuTK;
using osuTK.Graphics;

Expand All @@ -12,10 +13,11 @@ public partial class StrictHardBeatPiece : CircularProgress
{
public BindableFloat NoteSize = new(16f);
public BindableDouble AngleRange = new(25 * 0.75);
public BindableBool HighlightHardBeats = new(false);

public StrictHardBeatPiece()
{
Colour = Color4.White;
Colour = HighlightHardBeats.Value ? Color4.Orange : Color4.White;
Snootiful marked this conversation as resolved.
Show resolved Hide resolved
RelativeSizeAxes = Axes.Both;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Expand All @@ -28,14 +30,17 @@ public StrictHardBeatPiece()
Progress = val.NewValue / 360;
Rotation = -(float)(val.NewValue / 2);
}, true);
HighlightHardBeats.BindValueChanged(value => Colour = value.NewValue ? Color4.Orange : Color4.White);
}

[BackgroundDependencyLoader]
private void load()
private void load(TauRulesetConfigManager config)
{
// Size is set to zero here as to avoid standard fallback to original sprite's size (1,1),
// see: https://github.com/ppy/osu-framework/blob/603e15fb2e68826e55878dfc09e1d7414b7cdf90/osu.Framework/Graphics/Sprites/Sprite.cs#L181-L182
Size = Vector2.Zero;

config?.BindWith(TauRulesetSettings.HighlightHardBeats, HighlightHardBeats);
}

private float toNormalized(float value)
Expand Down
8 changes: 1 addition & 7 deletions osu.Game.Rulesets.Tau/UI/TauCachedProperties.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
using System;

Expand All @@ -12,7 +11,6 @@ public class TauCachedProperties : IDisposable
{
public readonly BindableDouble AngleRange = new(25);
public readonly BindableBool InverseModEnabled = new();
public Texture SliderTexture;

/// <summary>
/// Sets the range for the paddle.
Expand All @@ -23,10 +21,6 @@ public void SetRange(float cs)
AngleRange.Value = IBeatmapDifficultyInfo.DifficultyRange(cs, 75, 25, 10);
}

public void Dispose()
{
SliderTexture?.Dispose();
SliderTexture = null;
}
public void Dispose() {}
Snootiful marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading