mirror of
https://github.com/ppy/osu.git
synced 2025-01-26 12:45:09 +08:00
Merge branch 'current-star-rating' into player-loader-star-rating
This commit is contained in:
commit
004ce95f33
@ -1,28 +1,22 @@
|
|||||||
// 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.Collections.Generic;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.EmptyFreeform.Objects;
|
using osu.Game.Rulesets.EmptyFreeform.Objects;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.EmptyFreeform.Replays
|
namespace osu.Game.Rulesets.EmptyFreeform.Replays
|
||||||
{
|
{
|
||||||
public class EmptyFreeformAutoGenerator : AutoGenerator
|
public class EmptyFreeformAutoGenerator : AutoGenerator<EmptyFreeformReplayFrame>
|
||||||
{
|
{
|
||||||
protected Replay Replay;
|
|
||||||
protected List<ReplayFrame> Frames => Replay.Frames;
|
|
||||||
|
|
||||||
public new Beatmap<EmptyFreeformHitObject> Beatmap => (Beatmap<EmptyFreeformHitObject>)base.Beatmap;
|
public new Beatmap<EmptyFreeformHitObject> Beatmap => (Beatmap<EmptyFreeformHitObject>)base.Beatmap;
|
||||||
|
|
||||||
public EmptyFreeformAutoGenerator(IBeatmap beatmap)
|
public EmptyFreeformAutoGenerator(IBeatmap beatmap)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
Replay = new Replay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Replay Generate()
|
protected override void GenerateFrames()
|
||||||
{
|
{
|
||||||
Frames.Add(new EmptyFreeformReplayFrame());
|
Frames.Add(new EmptyFreeformReplayFrame());
|
||||||
|
|
||||||
@ -35,8 +29,6 @@ namespace osu.Game.Rulesets.EmptyFreeform.Replays
|
|||||||
// todo: add required inputs and extra frames.
|
// todo: add required inputs and extra frames.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Replay;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,22 @@
|
|||||||
// 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.Collections.Generic;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Pippidon.Objects;
|
using osu.Game.Rulesets.Pippidon.Objects;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Pippidon.Replays
|
namespace osu.Game.Rulesets.Pippidon.Replays
|
||||||
{
|
{
|
||||||
public class PippidonAutoGenerator : AutoGenerator
|
public class PippidonAutoGenerator : AutoGenerator<PippidonReplayFrame>
|
||||||
{
|
{
|
||||||
protected Replay Replay;
|
|
||||||
protected List<ReplayFrame> Frames => Replay.Frames;
|
|
||||||
|
|
||||||
public new Beatmap<PippidonHitObject> Beatmap => (Beatmap<PippidonHitObject>)base.Beatmap;
|
public new Beatmap<PippidonHitObject> Beatmap => (Beatmap<PippidonHitObject>)base.Beatmap;
|
||||||
|
|
||||||
public PippidonAutoGenerator(IBeatmap beatmap)
|
public PippidonAutoGenerator(IBeatmap beatmap)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
Replay = new Replay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Replay Generate()
|
protected override void GenerateFrames()
|
||||||
{
|
{
|
||||||
Frames.Add(new PippidonReplayFrame());
|
Frames.Add(new PippidonReplayFrame());
|
||||||
|
|
||||||
@ -34,8 +28,6 @@ namespace osu.Game.Rulesets.Pippidon.Replays
|
|||||||
Position = hitObject.Position,
|
Position = hitObject.Position,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Replay;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,22 @@
|
|||||||
// 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.Collections.Generic;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.EmptyScrolling.Objects;
|
using osu.Game.Rulesets.EmptyScrolling.Objects;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.EmptyScrolling.Replays
|
namespace osu.Game.Rulesets.EmptyScrolling.Replays
|
||||||
{
|
{
|
||||||
public class EmptyScrollingAutoGenerator : AutoGenerator
|
public class EmptyScrollingAutoGenerator : AutoGenerator<EmptyScrollingReplayFrame>
|
||||||
{
|
{
|
||||||
protected Replay Replay;
|
|
||||||
protected List<ReplayFrame> Frames => Replay.Frames;
|
|
||||||
|
|
||||||
public new Beatmap<EmptyScrollingHitObject> Beatmap => (Beatmap<EmptyScrollingHitObject>)base.Beatmap;
|
public new Beatmap<EmptyScrollingHitObject> Beatmap => (Beatmap<EmptyScrollingHitObject>)base.Beatmap;
|
||||||
|
|
||||||
public EmptyScrollingAutoGenerator(IBeatmap beatmap)
|
public EmptyScrollingAutoGenerator(IBeatmap beatmap)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
Replay = new Replay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Replay Generate()
|
protected override void GenerateFrames()
|
||||||
{
|
{
|
||||||
Frames.Add(new EmptyScrollingReplayFrame());
|
Frames.Add(new EmptyScrollingReplayFrame());
|
||||||
|
|
||||||
@ -34,8 +28,6 @@ namespace osu.Game.Rulesets.EmptyScrolling.Replays
|
|||||||
// todo: add required inputs and extra frames.
|
// todo: add required inputs and extra frames.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Replay;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,29 +2,23 @@
|
|||||||
// 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;
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Pippidon.Objects;
|
using osu.Game.Rulesets.Pippidon.Objects;
|
||||||
using osu.Game.Rulesets.Pippidon.UI;
|
using osu.Game.Rulesets.Pippidon.UI;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Pippidon.Replays
|
namespace osu.Game.Rulesets.Pippidon.Replays
|
||||||
{
|
{
|
||||||
public class PippidonAutoGenerator : AutoGenerator
|
public class PippidonAutoGenerator : AutoGenerator<PippidonReplayFrame>
|
||||||
{
|
{
|
||||||
protected Replay Replay;
|
|
||||||
protected List<ReplayFrame> Frames => Replay.Frames;
|
|
||||||
|
|
||||||
public new Beatmap<PippidonHitObject> Beatmap => (Beatmap<PippidonHitObject>)base.Beatmap;
|
public new Beatmap<PippidonHitObject> Beatmap => (Beatmap<PippidonHitObject>)base.Beatmap;
|
||||||
|
|
||||||
public PippidonAutoGenerator(IBeatmap beatmap)
|
public PippidonAutoGenerator(IBeatmap beatmap)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
Replay = new Replay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Replay Generate()
|
protected override void GenerateFrames()
|
||||||
{
|
{
|
||||||
int currentLane = 0;
|
int currentLane = 0;
|
||||||
|
|
||||||
@ -55,8 +49,6 @@ namespace osu.Game.Rulesets.Pippidon.Replays
|
|||||||
|
|
||||||
currentLane = hitObject.Lane;
|
currentLane = hitObject.Lane;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Replay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addFrame(double time, PippidonAction direction)
|
private void addFrame(double time, PippidonAction direction)
|
||||||
|
@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.UI;
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
@ -13,26 +12,19 @@ using osu.Game.Rulesets.Replays;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Replays
|
namespace osu.Game.Rulesets.Catch.Replays
|
||||||
{
|
{
|
||||||
internal class CatchAutoGenerator : AutoGenerator
|
internal class CatchAutoGenerator : AutoGenerator<CatchReplayFrame>
|
||||||
{
|
{
|
||||||
public const double RELEASE_DELAY = 20;
|
|
||||||
|
|
||||||
public new CatchBeatmap Beatmap => (CatchBeatmap)base.Beatmap;
|
public new CatchBeatmap Beatmap => (CatchBeatmap)base.Beatmap;
|
||||||
|
|
||||||
public CatchAutoGenerator(IBeatmap beatmap)
|
public CatchAutoGenerator(IBeatmap beatmap)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
Replay = new Replay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Replay Replay;
|
protected override void GenerateFrames()
|
||||||
|
|
||||||
private CatchReplayFrame currentFrame;
|
|
||||||
|
|
||||||
public override Replay Generate()
|
|
||||||
{
|
{
|
||||||
if (Beatmap.HitObjects.Count == 0)
|
if (Beatmap.HitObjects.Count == 0)
|
||||||
return Replay;
|
return;
|
||||||
|
|
||||||
// todo: add support for HT DT
|
// todo: add support for HT DT
|
||||||
const double dash_speed = Catcher.BASE_SPEED;
|
const double dash_speed = Catcher.BASE_SPEED;
|
||||||
@ -119,15 +111,11 @@ namespace osu.Game.Rulesets.Catch.Replays
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Replay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addFrame(double time, float? position = null, bool dashing = false)
|
private void addFrame(double time, float? position = null, bool dashing = false)
|
||||||
{
|
{
|
||||||
var last = currentFrame;
|
Frames.Add(new CatchReplayFrame(time, position, dashing, LastFrame));
|
||||||
currentFrame = new CatchReplayFrame(time, position, dashing, last);
|
|
||||||
Replay.Frames.Add(currentFrame);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -11,7 +10,7 @@ using osu.Game.Rulesets.Replays;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Replays
|
namespace osu.Game.Rulesets.Mania.Replays
|
||||||
{
|
{
|
||||||
internal class ManiaAutoGenerator : AutoGenerator
|
internal class ManiaAutoGenerator : AutoGenerator<ManiaReplayFrame>
|
||||||
{
|
{
|
||||||
public const double RELEASE_DELAY = 20;
|
public const double RELEASE_DELAY = 20;
|
||||||
|
|
||||||
@ -22,8 +21,6 @@ namespace osu.Game.Rulesets.Mania.Replays
|
|||||||
public ManiaAutoGenerator(ManiaBeatmap beatmap)
|
public ManiaAutoGenerator(ManiaBeatmap beatmap)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
Replay = new Replay();
|
|
||||||
|
|
||||||
columnActions = new ManiaAction[Beatmap.TotalColumns];
|
columnActions = new ManiaAction[Beatmap.TotalColumns];
|
||||||
|
|
||||||
var normalAction = ManiaAction.Key1;
|
var normalAction = ManiaAction.Key1;
|
||||||
@ -43,12 +40,10 @@ namespace osu.Game.Rulesets.Mania.Replays
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Replay Replay;
|
protected override void GenerateFrames()
|
||||||
|
|
||||||
public override Replay Generate()
|
|
||||||
{
|
{
|
||||||
if (Beatmap.HitObjects.Count == 0)
|
if (Beatmap.HitObjects.Count == 0)
|
||||||
return Replay;
|
return;
|
||||||
|
|
||||||
var pointGroups = generateActionPoints().GroupBy(a => a.Time).OrderBy(g => g.First().Time);
|
var pointGroups = generateActionPoints().GroupBy(a => a.Time).OrderBy(g => g.First().Time);
|
||||||
|
|
||||||
@ -70,10 +65,8 @@ namespace osu.Game.Rulesets.Mania.Replays
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Replay.Frames.Add(new ManiaReplayFrame(group.First().Time, actions.ToArray()));
|
Frames.Add(new ManiaReplayFrame(group.First().Time, actions.ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Replay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IActionPoint> generateActionPoints()
|
private IEnumerable<IActionPoint> generateActionPoints()
|
||||||
|
@ -2,10 +2,8 @@
|
|||||||
// 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;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||||
@ -13,7 +11,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Replays
|
namespace osu.Game.Rulesets.Taiko.Replays
|
||||||
{
|
{
|
||||||
public class TaikoAutoGenerator : AutoGenerator
|
public class TaikoAutoGenerator : AutoGenerator<TaikoReplayFrame>
|
||||||
{
|
{
|
||||||
public new TaikoBeatmap Beatmap => (TaikoBeatmap)base.Beatmap;
|
public new TaikoBeatmap Beatmap => (TaikoBeatmap)base.Beatmap;
|
||||||
|
|
||||||
@ -22,16 +20,12 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
|||||||
public TaikoAutoGenerator(IBeatmap beatmap)
|
public TaikoAutoGenerator(IBeatmap beatmap)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
Replay = new Replay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Replay Replay;
|
protected override void GenerateFrames()
|
||||||
protected List<ReplayFrame> Frames => Replay.Frames;
|
|
||||||
|
|
||||||
public override Replay Generate()
|
|
||||||
{
|
{
|
||||||
if (Beatmap.HitObjects.Count == 0)
|
if (Beatmap.HitObjects.Count == 0)
|
||||||
return Replay;
|
return;
|
||||||
|
|
||||||
bool hitButton = true;
|
bool hitButton = true;
|
||||||
|
|
||||||
@ -128,8 +122,6 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
|||||||
|
|
||||||
hitButton = !hitButton;
|
hitButton = !hitButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Replay;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Screens.Play.HUD;
|
using osu.Game.Screens.Play.HUD;
|
||||||
@ -20,24 +21,28 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuConfigManager config { get; set; }
|
private OsuConfigManager config { get; set; }
|
||||||
|
|
||||||
[SetUpSteps]
|
private void create(HealthProcessor healthProcessor)
|
||||||
public void SetUpSteps()
|
|
||||||
{
|
{
|
||||||
AddStep("create layer", () =>
|
AddStep("create layer", () =>
|
||||||
{
|
{
|
||||||
Child = layer = new FailingLayer();
|
Child = new HealthProcessorContainer(healthProcessor)
|
||||||
layer.BindHealthProcessor(new DrainingHealthProcessor(1));
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = layer = new FailingLayer()
|
||||||
|
};
|
||||||
|
|
||||||
layer.ShowHealth.BindTo(showHealth);
|
layer.ShowHealth.BindTo(showHealth);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("show health", () => showHealth.Value = true);
|
AddStep("show health", () => showHealth.Value = true);
|
||||||
AddStep("enable layer", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, true));
|
AddStep("enable layer", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, true));
|
||||||
AddUntilStep("layer is visible", () => layer.IsPresent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLayerFading()
|
public void TestLayerFading()
|
||||||
{
|
{
|
||||||
|
create(new DrainingHealthProcessor(0));
|
||||||
|
|
||||||
AddSliderStep("current health", 0.0, 1.0, 1.0, val =>
|
AddSliderStep("current health", 0.0, 1.0, 1.0, val =>
|
||||||
{
|
{
|
||||||
if (layer != null)
|
if (layer != null)
|
||||||
@ -53,6 +58,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestLayerDisabledViaConfig()
|
public void TestLayerDisabledViaConfig()
|
||||||
{
|
{
|
||||||
|
create(new DrainingHealthProcessor(0));
|
||||||
|
AddUntilStep("layer is visible", () => layer.IsPresent);
|
||||||
AddStep("disable layer", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, false));
|
AddStep("disable layer", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, false));
|
||||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||||
AddUntilStep("layer is not visible", () => !layer.IsPresent);
|
AddUntilStep("layer is not visible", () => !layer.IsPresent);
|
||||||
@ -61,7 +68,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestLayerVisibilityWithAccumulatingProcessor()
|
public void TestLayerVisibilityWithAccumulatingProcessor()
|
||||||
{
|
{
|
||||||
AddStep("bind accumulating processor", () => layer.BindHealthProcessor(new AccumulatingHealthProcessor(1)));
|
create(new AccumulatingHealthProcessor(1));
|
||||||
|
AddUntilStep("layer is not visible", () => !layer.IsPresent);
|
||||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||||
AddUntilStep("layer is not visible", () => !layer.IsPresent);
|
AddUntilStep("layer is not visible", () => !layer.IsPresent);
|
||||||
}
|
}
|
||||||
@ -69,7 +77,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestLayerVisibilityWithDrainingProcessor()
|
public void TestLayerVisibilityWithDrainingProcessor()
|
||||||
{
|
{
|
||||||
AddStep("bind accumulating processor", () => layer.BindHealthProcessor(new DrainingHealthProcessor(1)));
|
create(new DrainingHealthProcessor(0));
|
||||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||||
AddWaitStep("wait for potential fade", 10);
|
AddWaitStep("wait for potential fade", 10);
|
||||||
AddAssert("layer is still visible", () => layer.IsPresent);
|
AddAssert("layer is still visible", () => layer.IsPresent);
|
||||||
@ -78,6 +86,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestLayerVisibilityWithDifferentOptions()
|
public void TestLayerVisibilityWithDifferentOptions()
|
||||||
{
|
{
|
||||||
|
create(new DrainingHealthProcessor(0));
|
||||||
|
|
||||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||||
|
|
||||||
AddStep("don't show health", () => showHealth.Value = false);
|
AddStep("don't show health", () => showHealth.Value = false);
|
||||||
@ -96,5 +106,16 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddStep("enable FadePlayfieldWhenHealthLow", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, true));
|
AddStep("enable FadePlayfieldWhenHealthLow", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, true));
|
||||||
AddUntilStep("layer fade is visible", () => layer.IsPresent);
|
AddUntilStep("layer fade is visible", () => layer.IsPresent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class HealthProcessorContainer : Container
|
||||||
|
{
|
||||||
|
[Cached(typeof(HealthProcessor))]
|
||||||
|
private readonly HealthProcessor healthProcessor;
|
||||||
|
|
||||||
|
public HealthProcessorContainer(HealthProcessor healthProcessor)
|
||||||
|
{
|
||||||
|
this.healthProcessor = healthProcessor;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Cached]
|
[Cached]
|
||||||
private ScoreProcessor scoreProcessor = new ScoreProcessor();
|
private ScoreProcessor scoreProcessor = new ScoreProcessor();
|
||||||
|
|
||||||
|
[Cached(typeof(HealthProcessor))]
|
||||||
|
private HealthProcessor healthProcessor = new DrainingHealthProcessor(0);
|
||||||
|
|
||||||
// best way to check without exposing.
|
// best way to check without exposing.
|
||||||
private Drawable hideTarget => hudOverlay.KeyCounter;
|
private Drawable hideTarget => hudOverlay.KeyCounter;
|
||||||
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
|
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
|
||||||
@ -143,7 +146,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
AddStep("create overlay", () =>
|
AddStep("create overlay", () =>
|
||||||
{
|
{
|
||||||
hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty<Mod>());
|
hudOverlay = new HUDOverlay(scoreProcessor, null, Array.Empty<Mod>());
|
||||||
|
|
||||||
// Add any key just to display the key counter visually.
|
// Add any key just to display the key counter visually.
|
||||||
hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
|
hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
|
||||||
|
@ -21,6 +21,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Cached]
|
[Cached]
|
||||||
private readonly ScoreProcessor scoreProcessor = new ScoreProcessor();
|
private readonly ScoreProcessor scoreProcessor = new ScoreProcessor();
|
||||||
|
|
||||||
|
[Cached(typeof(HealthProcessor))]
|
||||||
|
private HealthProcessor healthProcessor = new DrainingHealthProcessor(0);
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public void SetUpSteps()
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
@ -34,7 +37,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap);
|
var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap);
|
||||||
|
|
||||||
var hudOverlay = new HUDOverlay(scoreProcessor, null, drawableRuleset, Array.Empty<Mod>())
|
var hudOverlay = new HUDOverlay(scoreProcessor, drawableRuleset, Array.Empty<Mod>())
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
@ -27,6 +27,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Cached]
|
[Cached]
|
||||||
private ScoreProcessor scoreProcessor = new ScoreProcessor();
|
private ScoreProcessor scoreProcessor = new ScoreProcessor();
|
||||||
|
|
||||||
|
[Cached(typeof(HealthProcessor))]
|
||||||
|
private HealthProcessor healthProcessor = new DrainingHealthProcessor(0);
|
||||||
|
|
||||||
private IEnumerable<HUDOverlay> hudOverlays => CreatedDrawables.OfType<HUDOverlay>();
|
private IEnumerable<HUDOverlay> hudOverlays => CreatedDrawables.OfType<HUDOverlay>();
|
||||||
|
|
||||||
// best way to check without exposing.
|
// best way to check without exposing.
|
||||||
@ -76,7 +79,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
SetContents(() =>
|
SetContents(() =>
|
||||||
{
|
{
|
||||||
hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty<Mod>());
|
hudOverlay = new HUDOverlay(scoreProcessor, null, Array.Empty<Mod>());
|
||||||
|
|
||||||
// Add any key just to display the key counter visually.
|
// Add any key just to display the key counter visually.
|
||||||
hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
|
hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
|
||||||
|
@ -4,11 +4,14 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Judgements;
|
using osu.Game.Rulesets.Osu.Judgements;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Screens.Play.HUD;
|
using osu.Game.Screens.Play.HUD;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
@ -19,6 +22,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
|
protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
|
||||||
|
|
||||||
|
[Cached(typeof(HealthProcessor))]
|
||||||
|
private HealthProcessor healthProcessor = new DrainingHealthProcessor(0);
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public void SetUpSteps()
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
@ -28,8 +34,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
});
|
});
|
||||||
AddStep(@"Reset all", delegate
|
AddStep(@"Reset all", delegate
|
||||||
{
|
{
|
||||||
foreach (var s in healthDisplays)
|
healthProcessor.Health.Value = 1;
|
||||||
s.Current.Value = 1;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,23 +43,21 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
AddRepeatStep(@"decrease hp", delegate
|
AddRepeatStep(@"decrease hp", delegate
|
||||||
{
|
{
|
||||||
foreach (var healthDisplay in healthDisplays)
|
healthProcessor.Health.Value -= 0.08f;
|
||||||
healthDisplay.Current.Value -= 0.08f;
|
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
AddRepeatStep(@"increase hp without flash", delegate
|
AddRepeatStep(@"increase hp without flash", delegate
|
||||||
{
|
{
|
||||||
foreach (var healthDisplay in healthDisplays)
|
healthProcessor.Health.Value += 0.1f;
|
||||||
healthDisplay.Current.Value += 0.1f;
|
|
||||||
}, 3);
|
}, 3);
|
||||||
|
|
||||||
AddRepeatStep(@"increase hp with flash", delegate
|
AddRepeatStep(@"increase hp with flash", delegate
|
||||||
{
|
{
|
||||||
foreach (var healthDisplay in healthDisplays)
|
healthProcessor.Health.Value += 0.1f;
|
||||||
|
healthProcessor.ApplyResult(new JudgementResult(new HitCircle(), new OsuJudgement())
|
||||||
{
|
{
|
||||||
healthDisplay.Current.Value += 0.1f;
|
Type = HitResult.Perfect
|
||||||
healthDisplay.Flash(new JudgementResult(null, new OsuJudgement()));
|
});
|
||||||
}
|
|
||||||
}, 3);
|
}, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,36 @@
|
|||||||
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Replays
|
namespace osu.Game.Rulesets.Replays
|
||||||
{
|
{
|
||||||
public abstract class AutoGenerator : IAutoGenerator
|
public abstract class AutoGenerator
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the auto replay and returns it.
|
/// The default duration of a key press in milliseconds.
|
||||||
/// Every subclass of OsuAutoGeneratorBase should implement this!
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract Replay Generate();
|
public const double KEY_UP_DELAY = 50;
|
||||||
|
|
||||||
#region Parameters
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The beatmap we're making.
|
/// The beatmap the autoplay is generated for.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IBeatmap Beatmap;
|
protected IBeatmap Beatmap { get; }
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
protected AutoGenerator(IBeatmap beatmap)
|
protected AutoGenerator(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
Beatmap = beatmap;
|
Beatmap = beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Constants
|
/// <summary>
|
||||||
|
/// Generate the replay of the autoplay.
|
||||||
// Shared amongst all modes
|
/// </summary>
|
||||||
public const double KEY_UP_DELAY = 50;
|
public abstract Replay Generate();
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
protected virtual HitObject GetNextObject(int currentIndex)
|
protected virtual HitObject GetNextObject(int currentIndex)
|
||||||
{
|
{
|
||||||
@ -44,4 +40,37 @@ namespace osu.Game.Rulesets.Replays
|
|||||||
return Beatmap.HitObjects[currentIndex + 1];
|
return Beatmap.HitObjects[currentIndex + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract class AutoGenerator<TFrame> : AutoGenerator
|
||||||
|
where TFrame : ReplayFrame
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The replay frames of the autoplay.
|
||||||
|
/// </summary>
|
||||||
|
protected readonly List<TFrame> Frames = new List<TFrame>();
|
||||||
|
|
||||||
|
[CanBeNull]
|
||||||
|
protected TFrame LastFrame => Frames.Count == 0 ? null : Frames[^1];
|
||||||
|
|
||||||
|
protected AutoGenerator(IBeatmap beatmap)
|
||||||
|
: base(beatmap)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed override Replay Generate()
|
||||||
|
{
|
||||||
|
Frames.Clear();
|
||||||
|
GenerateFrames();
|
||||||
|
|
||||||
|
return new Replay
|
||||||
|
{
|
||||||
|
Frames = Frames.OrderBy(frame => frame.Time).Cast<ReplayFrame>().ToList()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate the replay frames of the autoplay and populate <see cref="Frames"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void GenerateFrames();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
// 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 osu.Game.Replays;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Replays
|
|
||||||
{
|
|
||||||
public interface IAutoGenerator
|
|
||||||
{
|
|
||||||
Replay Generate();
|
|
||||||
}
|
|
||||||
}
|
|
@ -107,7 +107,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
GlowColour = colours.BlueDarker;
|
GlowColour = colours.BlueDarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Flash(JudgementResult result) => Scheduler.AddOnce(flash);
|
protected override void Flash(JudgementResult result) => Scheduler.AddOnce(flash);
|
||||||
|
|
||||||
private void flash()
|
private void flash()
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,6 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
private readonly Container boxes;
|
private readonly Container boxes;
|
||||||
|
|
||||||
private Bindable<bool> fadePlayfieldWhenHealthLow;
|
private Bindable<bool> fadePlayfieldWhenHealthLow;
|
||||||
private HealthProcessor healthProcessor;
|
|
||||||
|
|
||||||
public FailingLayer()
|
public FailingLayer()
|
||||||
{
|
{
|
||||||
@ -88,18 +87,10 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
updateState();
|
updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void BindHealthProcessor(HealthProcessor processor)
|
|
||||||
{
|
|
||||||
base.BindHealthProcessor(processor);
|
|
||||||
|
|
||||||
healthProcessor = processor;
|
|
||||||
updateState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
// Don't display ever if the ruleset is not using a draining health display.
|
// Don't display ever if the ruleset is not using a draining health display.
|
||||||
var showLayer = healthProcessor is DrainingHealthProcessor && fadePlayfieldWhenHealthLow.Value && ShowHealth.Value;
|
var showLayer = HealthProcessor is DrainingHealthProcessor && fadePlayfieldWhenHealthLow.Value && ShowHealth.Value;
|
||||||
this.FadeTo(showLayer ? 1 : 0, fade_time, Easing.OutQuint);
|
this.FadeTo(showLayer ? 1 : 0, fade_time, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
@ -11,26 +12,43 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A container for components displaying the current player health.
|
/// A container for components displaying the current player health.
|
||||||
/// Gets bound automatically to the <see cref="HealthProcessor"/> when inserted to <see cref="DrawableRuleset.Overlays"/> hierarchy.
|
/// Gets bound automatically to the <see cref="Rulesets.Scoring.HealthProcessor"/> when inserted to <see cref="DrawableRuleset.Overlays"/> hierarchy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class HealthDisplay : Container, IHealthDisplay
|
public abstract class HealthDisplay : Container
|
||||||
{
|
{
|
||||||
|
[Resolved]
|
||||||
|
protected HealthProcessor HealthProcessor { get; private set; }
|
||||||
|
|
||||||
public Bindable<double> Current { get; } = new BindableDouble(1)
|
public Bindable<double> Current { get; } = new BindableDouble(1)
|
||||||
{
|
{
|
||||||
MinValue = 0,
|
MinValue = 0,
|
||||||
MaxValue = 1
|
MaxValue = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
public virtual void Flash(JudgementResult result)
|
protected virtual void Flash(JudgementResult result)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
[BackgroundDependencyLoader]
|
||||||
/// Bind the tracked fields of <see cref="HealthProcessor"/> to this health display.
|
private void load()
|
||||||
/// </summary>
|
|
||||||
public virtual void BindHealthProcessor(HealthProcessor processor)
|
|
||||||
{
|
{
|
||||||
Current.BindTo(processor.Health);
|
Current.BindTo(HealthProcessor.Health);
|
||||||
|
|
||||||
|
HealthProcessor.NewJudgement += onNewJudgement;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onNewJudgement(JudgementResult judgement)
|
||||||
|
{
|
||||||
|
if (judgement.IsHit && judgement.Type != HitResult.IgnoreHit)
|
||||||
|
Flash(judgement);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
if (HealthProcessor != null)
|
||||||
|
HealthProcessor.NewJudgement -= onNewJudgement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
// 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 osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.HUD
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An interface providing a set of methods to update a health display.
|
|
||||||
/// </summary>
|
|
||||||
public interface IHealthDisplay : IDrawable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The current health to be displayed.
|
|
||||||
/// </summary>
|
|
||||||
Bindable<double> Current { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Flash the display for a specified result type.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="result">The result type.</param>
|
|
||||||
void Flash(JudgementResult result);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +1,16 @@
|
|||||||
// 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 osu.Framework.Bindables;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.HUD
|
namespace osu.Game.Screens.Play.HUD
|
||||||
{
|
{
|
||||||
public class SkinnableHealthDisplay : SkinnableDrawable, IHealthDisplay
|
public class SkinnableHealthDisplay : SkinnableDrawable
|
||||||
{
|
{
|
||||||
public Bindable<double> Current { get; } = new BindableDouble(1)
|
|
||||||
{
|
|
||||||
MinValue = 0,
|
|
||||||
MaxValue = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
public void Flash(JudgementResult result) => skinnedCounter?.Flash(result);
|
|
||||||
|
|
||||||
private HealthProcessor processor;
|
|
||||||
|
|
||||||
public void BindHealthProcessor(HealthProcessor processor)
|
|
||||||
{
|
|
||||||
if (this.processor != null)
|
|
||||||
throw new InvalidOperationException("Can't bind to a processor more than once");
|
|
||||||
|
|
||||||
this.processor = processor;
|
|
||||||
|
|
||||||
Current.BindTo(processor.Health);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SkinnableHealthDisplay()
|
public SkinnableHealthDisplay()
|
||||||
: base(new HUDSkinComponent(HUDSkinComponents.HealthDisplay), _ => new DefaultHealthDisplay())
|
: base(new HUDSkinComponent(HUDSkinComponents.HealthDisplay), _ => new DefaultHealthDisplay())
|
||||||
{
|
{
|
||||||
CentreComponent = false;
|
CentreComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IHealthDisplay skinnedCounter;
|
|
||||||
|
|
||||||
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
|
||||||
{
|
|
||||||
base.SkinChanged(skin, allowFallback);
|
|
||||||
|
|
||||||
skinnedCounter = Drawable as IHealthDisplay;
|
|
||||||
skinnedCounter?.Current.BindTo(Current);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,6 @@ namespace osu.Game.Screens.Play
|
|||||||
public Bindable<bool> ShowHealthbar = new Bindable<bool>(true);
|
public Bindable<bool> ShowHealthbar = new Bindable<bool>(true);
|
||||||
|
|
||||||
private readonly ScoreProcessor scoreProcessor;
|
private readonly ScoreProcessor scoreProcessor;
|
||||||
private readonly HealthProcessor healthProcessor;
|
|
||||||
private readonly DrawableRuleset drawableRuleset;
|
private readonly DrawableRuleset drawableRuleset;
|
||||||
private readonly IReadOnlyList<Mod> mods;
|
private readonly IReadOnlyList<Mod> mods;
|
||||||
|
|
||||||
@ -75,10 +74,9 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
private IEnumerable<Drawable> hideTargets => new Drawable[] { visibilityContainer, KeyCounter, topRightElements };
|
private IEnumerable<Drawable> hideTargets => new Drawable[] { visibilityContainer, KeyCounter, topRightElements };
|
||||||
|
|
||||||
public HUDOverlay(ScoreProcessor scoreProcessor, HealthProcessor healthProcessor, DrawableRuleset drawableRuleset, IReadOnlyList<Mod> mods)
|
public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IReadOnlyList<Mod> mods)
|
||||||
{
|
{
|
||||||
this.scoreProcessor = scoreProcessor;
|
this.scoreProcessor = scoreProcessor;
|
||||||
this.healthProcessor = healthProcessor;
|
|
||||||
this.drawableRuleset = drawableRuleset;
|
this.drawableRuleset = drawableRuleset;
|
||||||
this.mods = mods;
|
this.mods = mods;
|
||||||
|
|
||||||
@ -158,12 +156,6 @@ namespace osu.Game.Screens.Play
|
|||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
|
private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
|
||||||
{
|
{
|
||||||
if (scoreProcessor != null)
|
|
||||||
BindScoreProcessor(scoreProcessor);
|
|
||||||
|
|
||||||
if (healthProcessor != null)
|
|
||||||
BindHealthProcessor(healthProcessor);
|
|
||||||
|
|
||||||
if (drawableRuleset != null)
|
if (drawableRuleset != null)
|
||||||
{
|
{
|
||||||
BindDrawableRuleset(drawableRuleset);
|
BindDrawableRuleset(drawableRuleset);
|
||||||
@ -318,24 +310,6 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay();
|
protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay();
|
||||||
|
|
||||||
protected virtual void BindScoreProcessor(ScoreProcessor processor)
|
|
||||||
{
|
|
||||||
if (HealthDisplay is IHealthDisplay shd)
|
|
||||||
{
|
|
||||||
processor.NewJudgement += judgement =>
|
|
||||||
{
|
|
||||||
if (judgement.IsHit && judgement.Type != HitResult.IgnoreHit)
|
|
||||||
shd.Flash(judgement);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void BindHealthProcessor(HealthProcessor processor)
|
|
||||||
{
|
|
||||||
HealthDisplay?.BindHealthProcessor(processor);
|
|
||||||
FailingLayer?.BindHealthProcessor(processor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OnPressed(GlobalAction action)
|
public bool OnPressed(GlobalAction action)
|
||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
|
@ -208,6 +208,8 @@ namespace osu.Game.Screens.Play
|
|||||||
HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime);
|
HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime);
|
||||||
HealthProcessor.ApplyBeatmap(playableBeatmap);
|
HealthProcessor.ApplyBeatmap(playableBeatmap);
|
||||||
|
|
||||||
|
dependencies.CacheAs(HealthProcessor);
|
||||||
|
|
||||||
if (!ScoreProcessor.Mode.Disabled)
|
if (!ScoreProcessor.Mode.Disabled)
|
||||||
config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
|
config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
|
||||||
|
|
||||||
@ -343,7 +345,7 @@ namespace osu.Game.Screens.Play
|
|||||||
// display the cursor above some HUD elements.
|
// display the cursor above some HUD elements.
|
||||||
DrawableRuleset.Cursor?.CreateProxy() ?? new Container(),
|
DrawableRuleset.Cursor?.CreateProxy() ?? new Container(),
|
||||||
DrawableRuleset.ResumeOverlay?.CreateProxy() ?? new Container(),
|
DrawableRuleset.ResumeOverlay?.CreateProxy() ?? new Container(),
|
||||||
HUDOverlay = new HUDOverlay(ScoreProcessor, HealthProcessor, DrawableRuleset, Mods.Value)
|
HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, Mods.Value)
|
||||||
{
|
{
|
||||||
HoldToQuit =
|
HoldToQuit =
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,7 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Containers;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -25,23 +25,7 @@ namespace osu.Game.Screens.Ranking.Expanded
|
|||||||
public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue<StarDifficulty?>
|
public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue<StarDifficulty?>
|
||||||
{
|
{
|
||||||
private Box background;
|
private Box background;
|
||||||
private OsuSpriteText wholePart;
|
private OsuTextFlowContainer textFlow;
|
||||||
private OsuSpriteText fractionPart;
|
|
||||||
|
|
||||||
private double displayedStarRating;
|
|
||||||
|
|
||||||
protected double DisplayedStarRating
|
|
||||||
{
|
|
||||||
get => displayedStarRating;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
displayedStarRating = value;
|
|
||||||
|
|
||||||
var starRatingParts = value.ToString("0.00", CultureInfo.InvariantCulture).Split('.');
|
|
||||||
wholePart.Text = starRatingParts[0];
|
|
||||||
fractionPart.Text = starRatingParts[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; }
|
private OsuColour colours { get; set; }
|
||||||
@ -105,40 +89,13 @@ namespace osu.Game.Screens.Ranking.Expanded
|
|||||||
Icon = FontAwesome.Solid.Star,
|
Icon = FontAwesome.Solid.Star,
|
||||||
Colour = Color4.Black
|
Colour = Color4.Black
|
||||||
},
|
},
|
||||||
new FillFlowContainer
|
textFlow = new OsuTextFlowContainer(s => s.Font = OsuFont.Numeric.With(weight: FontWeight.Black))
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
Children = new[]
|
TextAnchor = Anchor.BottomLeft,
|
||||||
{
|
|
||||||
wholePart = new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
Colour = Color4.Black,
|
|
||||||
Font = OsuFont.Numeric.With(size: 14, weight: FontWeight.Black),
|
|
||||||
UseFullGlyphHeight = false,
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
Colour = Color4.Black,
|
|
||||||
Text = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator,
|
|
||||||
Font = OsuFont.Numeric.With(size: 7, weight: FontWeight.Black),
|
|
||||||
UseFullGlyphHeight = false,
|
|
||||||
},
|
|
||||||
fractionPart = new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
Colour = Color4.Black,
|
|
||||||
Font = OsuFont.Numeric.With(size: 7, weight: FontWeight.Black),
|
|
||||||
UseFullGlyphHeight = false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,21 +115,39 @@ namespace osu.Game.Screens.Ranking.Expanded
|
|||||||
const double duration = 400;
|
const double duration = 400;
|
||||||
const Easing easing = Easing.OutQuint;
|
const Easing easing = Easing.OutQuint;
|
||||||
|
|
||||||
ColourInfo backgroundColour;
|
double stars = Current.Value?.Stars ?? 0.00f;
|
||||||
|
|
||||||
|
var starRatingParts = stars.ToString("0.00", CultureInfo.InvariantCulture).Split('.');
|
||||||
|
string wholePart = starRatingParts[0];
|
||||||
|
string fractionPart = starRatingParts[1];
|
||||||
|
string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
|
||||||
|
|
||||||
if (Current.Value == null)
|
if (Current.Value == null)
|
||||||
backgroundColour = Color4.SlateGray.Opacity(0.3f);
|
background.FadeColour(Color4.SlateGray.Opacity(0.3f));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var rating = Current.Value.Value.DifficultyRating;
|
var rating = Current.Value.Value.DifficultyRating;
|
||||||
|
|
||||||
backgroundColour = rating == DifficultyRating.ExpertPlus
|
background.FadeColour(rating == DifficultyRating.ExpertPlus
|
||||||
? ColourInfo.GradientVertical(Color4Extensions.FromHex("#C1C1C1"), Color4Extensions.FromHex("#595959"))
|
? ColourInfo.GradientVertical(Color4Extensions.FromHex("#C1C1C1"), Color4Extensions.FromHex("#595959"))
|
||||||
: (ColourInfo)colours.ForDifficultyRating(rating);
|
: (ColourInfo)colours.ForDifficultyRating(rating), duration, easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
background.FadeColour(backgroundColour, duration, easing);
|
textFlow.Clear();
|
||||||
this.TransformTo(nameof(DisplayedStarRating), Current.Value?.Stars ?? 0.0f, duration, easing);
|
|
||||||
|
textFlow.AddText($"{wholePart}", s =>
|
||||||
|
{
|
||||||
|
s.Colour = Color4.Black;
|
||||||
|
s.Font = s.Font.With(size: 14);
|
||||||
|
s.UseFullGlyphHeight = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
textFlow.AddText($"{separator}{fractionPart}", s =>
|
||||||
|
{
|
||||||
|
s.Colour = Color4.Black;
|
||||||
|
s.Font = s.Font.With(size: 7);
|
||||||
|
s.UseFullGlyphHeight = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
public class LegacyHealthDisplay : CompositeDrawable, IHealthDisplay, ISkinnableComponent
|
public class LegacyHealthDisplay : HealthDisplay
|
||||||
{
|
{
|
||||||
private const double epic_cutoff = 0.5;
|
private const double epic_cutoff = 0.5;
|
||||||
|
|
||||||
@ -28,12 +28,6 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
private bool isNewStyle;
|
private bool isNewStyle;
|
||||||
|
|
||||||
public Bindable<double> Current { get; } = new BindableDouble(1)
|
|
||||||
{
|
|
||||||
MinValue = 0,
|
|
||||||
MaxValue = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
public LegacyHealthDisplay(Skin skin)
|
public LegacyHealthDisplay(Skin skin)
|
||||||
{
|
{
|
||||||
this.skin = skin;
|
this.skin = skin;
|
||||||
@ -83,7 +77,7 @@ namespace osu.Game.Skinning
|
|||||||
marker.Position = fill.Position + new Vector2(fill.DrawWidth, isNewStyle ? fill.DrawHeight / 2 : 0);
|
marker.Position = fill.Position + new Vector2(fill.DrawWidth, isNewStyle ? fill.DrawHeight / 2 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Flash(JudgementResult result) => marker.Flash(result);
|
protected override void Flash(JudgementResult result) => marker.Flash(result);
|
||||||
|
|
||||||
private static Texture getTexture(Skin skin, string name) => skin.GetTexture($"scorebar-{name}");
|
private static Texture getTexture(Skin skin, string name) => skin.GetTexture($"scorebar-{name}");
|
||||||
|
|
||||||
@ -254,7 +248,7 @@ namespace osu.Game.Skinning
|
|||||||
Main.ScaleTo(1.4f).Then().ScaleTo(1, 200, Easing.Out);
|
Main.ScaleTo(1.4f).Then().ScaleTo(1, 200, Easing.Out);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LegacyHealthPiece : CompositeDrawable, IHealthDisplay
|
public class LegacyHealthPiece : CompositeDrawable
|
||||||
{
|
{
|
||||||
public Bindable<double> Current { get; } = new Bindable<double>();
|
public Bindable<double> Current { get; } = new Bindable<double>();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user