Add break support

This commit is contained in:
Dan Balasescu 2024-02-15 22:05:25 +09:00
parent d1a51b474c
commit 878fb2d10d
No known key found for this signature in database
4 changed files with 78 additions and 16 deletions

View File

@ -7,8 +7,12 @@
using osu.Framework.Graphics.Shapes;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Timing;
using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Objects;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests.Mods
@ -64,6 +68,21 @@ public void TestMaxCoverageHalfWidth()
AddStep("set playfield width to 0.5", () => Player.Width = 0.5f);
}
[Test]
public void TestNoCoverageDuringBreak()
{
CreateModTest(new ModTestData
{
Mod = new ManiaModHidden(),
Beatmap = new Beatmap
{
HitObjects = Enumerable.Range(1, 100).Select(i => (HitObject)new Note { StartTime = 1000 + 200 * i }).ToList(),
Breaks = { new BreakPeriod(2000, 28000) }
},
PassCondition = () => Player.IsBreakTime.Value && checkCoverage(0)
});
}
private bool checkCoverage(float expected)
{
Drawable? cover = this.ChildrenOfType<PlayfieldCoveringWrapper>().FirstOrDefault();

View File

@ -7,8 +7,12 @@
using osu.Framework.Graphics.Shapes;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Timing;
using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Objects;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests.Mods
@ -64,6 +68,21 @@ public void TestMaxCoverageHalfWidth()
AddStep("set playfield width to 0.5", () => Player.Width = 0.5f);
}
[Test]
public void TestNoCoverageDuringBreak()
{
CreateModTest(new ModTestData
{
Mod = new ManiaModHidden(),
Beatmap = new Beatmap
{
HitObjects = Enumerable.Range(1, 100).Select(i => (HitObject)new Note { StartTime = 1000 + 200 * i }).ToList(),
Breaks = { new BreakPeriod(2000, 28000) }
},
PassCondition = () => Player.IsBreakTime.Value && checkCoverage(0)
});
}
private bool checkCoverage(float expected)
{
Drawable? cover = this.ChildrenOfType<PlayfieldCoveringWrapper>().FirstOrDefault();

View File

@ -9,12 +9,15 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Skinning;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Mania.Mods
{
public partial class ManiaModHidden : ManiaModWithPlayfieldCover
public partial class ManiaModHidden : ManiaModWithPlayfieldCover, IApplicableToPlayer, IUpdatableByPlayfield
{
/// <summary>
/// osu!stable is referenced to 768px.
@ -37,6 +40,7 @@ public partial class ManiaModHidden : ManiaModWithPlayfieldCover
public override BindableNumber<float> Coverage { get; } = new BindableFloat(MIN_COVERAGE);
protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AgainstScroll;
private readonly IBindable<bool> isBreakTime = new Bindable<bool>();
private readonly BindableInt combo = new BindableInt();
public override void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
@ -45,12 +49,19 @@ public override void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
combo.UnbindAll();
combo.BindTo(scoreProcessor.Combo);
combo.BindValueChanged(c =>
{
Coverage.Value = Math.Min(
MAX_COVERAGE / reference_playfield_height,
MIN_COVERAGE / reference_playfield_height + c.NewValue * coverage_increase_per_combo / reference_playfield_height);
}, true);
}
public void ApplyToPlayer(Player player)
{
isBreakTime.UnbindAll();
isBreakTime.BindTo(player.IsBreakTime);
}
public void Update(Playfield playfield)
{
Coverage.Value = isBreakTime.Value
? 0
: Math.Min(MAX_COVERAGE, MIN_COVERAGE + combo.Value * coverage_increase_per_combo) / reference_playfield_height;
}
protected override PlayfieldCoveringWrapper CreateCover(Drawable content) => new LegacyPlayfieldCover(content);

View File

@ -43,7 +43,7 @@ public partial class PlayfieldCoveringWrapper : CompositeDrawable
private readonly IBindable<ScrollingDirection> scrollDirection = new Bindable<ScrollingDirection>();
private float currentCoverage;
private float currentCoverageHeight;
public PlayfieldCoveringWrapper(Drawable content)
{
@ -106,23 +106,36 @@ private void load(IScrollingInfo scrollingInfo)
protected override void LoadComplete()
{
base.LoadComplete();
updateHeight(Coverage.Value);
updateCoverSize(true);
}
protected override void Update()
{
base.Update();
updateHeight((float)Interpolation.DampContinuously(currentCoverage, Coverage.Value, 25, Math.Abs(Time.Elapsed)));
updateCoverSize(false);
}
private void updateHeight(float coverage)
private void updateCoverSize(bool instant)
{
filled.Height = GetHeight(coverage);
gradient.Y = -GetHeight(coverage);
float targetCoverage;
float targetAlpha;
currentCoverage = coverage;
if (instant)
{
targetCoverage = Coverage.Value;
targetAlpha = Coverage.Value > 0 ? 1 : 0;
}
else
{
targetCoverage = (float)Interpolation.DampContinuously(currentCoverageHeight, Coverage.Value, 25, Math.Abs(Time.Elapsed));
targetAlpha = (float)Interpolation.DampContinuously(gradient.Alpha, Coverage.Value > 0 ? 1 : 0, 25, Math.Abs(Time.Elapsed));
}
filled.Height = GetHeight(targetCoverage);
gradient.Y = -GetHeight(targetCoverage);
gradient.Alpha = targetAlpha;
currentCoverageHeight = targetCoverage;
}
protected virtual float GetHeight(float coverage) => coverage;