mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 17:07:38 +08:00
Merge remote-tracking branch 'refs/remotes/ppy/master' into news-sidebar-new
This commit is contained in:
commit
fbf8b198cd
@ -1,28 +1,22 @@
|
||||
// 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.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.EmptyFreeform.Objects;
|
||||
using osu.Game.Rulesets.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 EmptyFreeformAutoGenerator(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
Replay = new Replay();
|
||||
}
|
||||
|
||||
public override Replay Generate()
|
||||
protected override void GenerateFrames()
|
||||
{
|
||||
Frames.Add(new EmptyFreeformReplayFrame());
|
||||
|
||||
@ -35,8 +29,6 @@ namespace osu.Game.Rulesets.EmptyFreeform.Replays
|
||||
// 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.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Pippidon.Objects;
|
||||
using osu.Game.Rulesets.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 PippidonAutoGenerator(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
Replay = new Replay();
|
||||
}
|
||||
|
||||
public override Replay Generate()
|
||||
protected override void GenerateFrames()
|
||||
{
|
||||
Frames.Add(new PippidonReplayFrame());
|
||||
|
||||
@ -34,8 +28,6 @@ namespace osu.Game.Rulesets.Pippidon.Replays
|
||||
Position = hitObject.Position,
|
||||
});
|
||||
}
|
||||
|
||||
return Replay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,22 @@
|
||||
// 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.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.EmptyScrolling.Objects;
|
||||
using osu.Game.Rulesets.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 EmptyScrollingAutoGenerator(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
Replay = new Replay();
|
||||
}
|
||||
|
||||
public override Replay Generate()
|
||||
protected override void GenerateFrames()
|
||||
{
|
||||
Frames.Add(new EmptyScrollingReplayFrame());
|
||||
|
||||
@ -34,8 +28,6 @@ namespace osu.Game.Rulesets.EmptyScrolling.Replays
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Pippidon.Objects;
|
||||
using osu.Game.Rulesets.Pippidon.UI;
|
||||
using osu.Game.Rulesets.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 PippidonAutoGenerator(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
Replay = new Replay();
|
||||
}
|
||||
|
||||
public override Replay Generate()
|
||||
protected override void GenerateFrames()
|
||||
{
|
||||
int currentLane = 0;
|
||||
|
||||
@ -55,8 +49,6 @@ namespace osu.Game.Rulesets.Pippidon.Replays
|
||||
|
||||
currentLane = hitObject.Lane;
|
||||
}
|
||||
|
||||
return Replay;
|
||||
}
|
||||
|
||||
private void addFrame(double time, PippidonAction direction)
|
||||
|
@ -5,7 +5,6 @@ using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.UI;
|
||||
@ -13,26 +12,19 @@ using osu.Game.Rulesets.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 CatchAutoGenerator(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
Replay = new Replay();
|
||||
}
|
||||
|
||||
protected Replay Replay;
|
||||
|
||||
private CatchReplayFrame currentFrame;
|
||||
|
||||
public override Replay Generate()
|
||||
protected override void GenerateFrames()
|
||||
{
|
||||
if (Beatmap.HitObjects.Count == 0)
|
||||
return Replay;
|
||||
return;
|
||||
|
||||
// todo: add support for HT DT
|
||||
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)
|
||||
{
|
||||
var last = currentFrame;
|
||||
currentFrame = new CatchReplayFrame(time, position, dashing, last);
|
||||
Replay.Frames.Add(currentFrame);
|
||||
Frames.Add(new CatchReplayFrame(time, position, dashing, LastFrame));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
@ -11,7 +10,7 @@ using osu.Game.Rulesets.Replays;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Replays
|
||||
{
|
||||
internal class ManiaAutoGenerator : AutoGenerator
|
||||
internal class ManiaAutoGenerator : AutoGenerator<ManiaReplayFrame>
|
||||
{
|
||||
public const double RELEASE_DELAY = 20;
|
||||
|
||||
@ -22,8 +21,6 @@ namespace osu.Game.Rulesets.Mania.Replays
|
||||
public ManiaAutoGenerator(ManiaBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
Replay = new Replay();
|
||||
|
||||
columnActions = new ManiaAction[Beatmap.TotalColumns];
|
||||
|
||||
var normalAction = ManiaAction.Key1;
|
||||
@ -43,12 +40,10 @@ namespace osu.Game.Rulesets.Mania.Replays
|
||||
}
|
||||
}
|
||||
|
||||
protected Replay Replay;
|
||||
|
||||
public override Replay Generate()
|
||||
protected override void GenerateFrames()
|
||||
{
|
||||
if (Beatmap.HitObjects.Count == 0)
|
||||
return Replay;
|
||||
return;
|
||||
|
||||
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()
|
||||
|
@ -2,10 +2,8 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||
@ -13,7 +11,7 @@ using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
public class TaikoAutoGenerator : AutoGenerator
|
||||
public class TaikoAutoGenerator : AutoGenerator<TaikoReplayFrame>
|
||||
{
|
||||
public new TaikoBeatmap Beatmap => (TaikoBeatmap)base.Beatmap;
|
||||
|
||||
@ -22,16 +20,12 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
public TaikoAutoGenerator(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
Replay = new Replay();
|
||||
}
|
||||
|
||||
protected Replay Replay;
|
||||
protected List<ReplayFrame> Frames => Replay.Frames;
|
||||
|
||||
public override Replay Generate()
|
||||
protected override void GenerateFrames()
|
||||
{
|
||||
if (Beatmap.HitObjects.Count == 0)
|
||||
return Replay;
|
||||
return;
|
||||
|
||||
bool hitButton = true;
|
||||
|
||||
@ -128,8 +122,6 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
|
||||
hitButton = !hitButton;
|
||||
}
|
||||
|
||||
return Replay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,8 @@
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
@ -20,24 +21,28 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Resolved]
|
||||
private OsuConfigManager config { get; set; }
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetUpSteps()
|
||||
private void create(HealthProcessor healthProcessor)
|
||||
{
|
||||
AddStep("create layer", () =>
|
||||
{
|
||||
Child = layer = new FailingLayer();
|
||||
layer.BindHealthProcessor(new DrainingHealthProcessor(1));
|
||||
Child = new HealthProcessorContainer(healthProcessor)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = layer = new FailingLayer()
|
||||
};
|
||||
|
||||
layer.ShowHealth.BindTo(showHealth);
|
||||
});
|
||||
|
||||
AddStep("show health", () => showHealth.Value = true);
|
||||
AddStep("enable layer", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, true));
|
||||
AddUntilStep("layer is visible", () => layer.IsPresent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLayerFading()
|
||||
{
|
||||
create(new DrainingHealthProcessor(0));
|
||||
|
||||
AddSliderStep("current health", 0.0, 1.0, 1.0, val =>
|
||||
{
|
||||
if (layer != null)
|
||||
@ -53,6 +58,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Test]
|
||||
public void TestLayerDisabledViaConfig()
|
||||
{
|
||||
create(new DrainingHealthProcessor(0));
|
||||
AddUntilStep("layer is visible", () => layer.IsPresent);
|
||||
AddStep("disable layer", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, false));
|
||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||
AddUntilStep("layer is not visible", () => !layer.IsPresent);
|
||||
@ -61,7 +68,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Test]
|
||||
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);
|
||||
AddUntilStep("layer is not visible", () => !layer.IsPresent);
|
||||
}
|
||||
@ -69,7 +77,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Test]
|
||||
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);
|
||||
AddWaitStep("wait for potential fade", 10);
|
||||
AddAssert("layer is still visible", () => layer.IsPresent);
|
||||
@ -78,6 +86,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Test]
|
||||
public void TestLayerVisibilityWithDifferentOptions()
|
||||
{
|
||||
create(new DrainingHealthProcessor(0));
|
||||
|
||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||
|
||||
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));
|
||||
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]
|
||||
private ScoreProcessor scoreProcessor = new ScoreProcessor();
|
||||
|
||||
[Cached(typeof(HealthProcessor))]
|
||||
private HealthProcessor healthProcessor = new DrainingHealthProcessor(0);
|
||||
|
||||
// best way to check without exposing.
|
||||
private Drawable hideTarget => hudOverlay.KeyCounter;
|
||||
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
|
||||
@ -143,7 +146,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
AddStep("create overlay", () =>
|
||||
{
|
||||
hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty<Mod>());
|
||||
hudOverlay = new HUDOverlay(null, Array.Empty<Mod>());
|
||||
|
||||
// Add any key just to display the key counter visually.
|
||||
hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
|
||||
|
@ -2,15 +2,16 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Catch.Scoring;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Scoring;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Scoring;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko.Scoring;
|
||||
@ -20,14 +21,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestSceneHitErrorMeter : OsuTestScene
|
||||
{
|
||||
private BarHitErrorMeter barMeter;
|
||||
private BarHitErrorMeter barMeter2;
|
||||
private BarHitErrorMeter barMeter3;
|
||||
private ColourHitErrorMeter colourMeter;
|
||||
private ColourHitErrorMeter colourMeter2;
|
||||
private ColourHitErrorMeter colourMeter3;
|
||||
private HitWindows hitWindows;
|
||||
|
||||
[Cached]
|
||||
private ScoreProcessor scoreProcessor = new ScoreProcessor();
|
||||
|
||||
public TestSceneHitErrorMeter()
|
||||
{
|
||||
recreateDisplay(new OsuHitWindows(), 5);
|
||||
@ -105,40 +103,40 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
}
|
||||
});
|
||||
|
||||
Add(barMeter = new BarHitErrorMeter(hitWindows, true)
|
||||
Add(new BarHitErrorMeter(hitWindows, true)
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
});
|
||||
|
||||
Add(barMeter2 = new BarHitErrorMeter(hitWindows, false)
|
||||
Add(new BarHitErrorMeter(hitWindows, false)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
});
|
||||
|
||||
Add(barMeter3 = new BarHitErrorMeter(hitWindows, true)
|
||||
Add(new BarHitErrorMeter(hitWindows, true)
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Rotation = 270,
|
||||
});
|
||||
|
||||
Add(colourMeter = new ColourHitErrorMeter(hitWindows)
|
||||
Add(new ColourHitErrorMeter(hitWindows)
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Margin = new MarginPadding { Right = 50 }
|
||||
});
|
||||
|
||||
Add(colourMeter2 = new ColourHitErrorMeter(hitWindows)
|
||||
Add(new ColourHitErrorMeter(hitWindows)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Left = 50 }
|
||||
});
|
||||
|
||||
Add(colourMeter3 = new ColourHitErrorMeter(hitWindows)
|
||||
Add(new ColourHitErrorMeter(hitWindows)
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.CentreLeft,
|
||||
@ -149,18 +147,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
private void newJudgement(double offset = 0)
|
||||
{
|
||||
var judgement = new JudgementResult(new HitObject(), new Judgement())
|
||||
scoreProcessor.ApplyResult(new JudgementResult(new HitCircle { HitWindows = hitWindows }, new Judgement())
|
||||
{
|
||||
TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset,
|
||||
Type = HitResult.Perfect,
|
||||
};
|
||||
|
||||
barMeter.OnNewJudgement(judgement);
|
||||
barMeter2.OnNewJudgement(judgement);
|
||||
barMeter3.OnNewJudgement(judgement);
|
||||
colourMeter.OnNewJudgement(judgement);
|
||||
colourMeter2.OnNewJudgement(judgement);
|
||||
colourMeter3.OnNewJudgement(judgement);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Cached]
|
||||
private readonly ScoreProcessor scoreProcessor = new ScoreProcessor();
|
||||
|
||||
[Cached(typeof(HealthProcessor))]
|
||||
private HealthProcessor healthProcessor = new DrainingHealthProcessor(0);
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetUpSteps()
|
||||
{
|
||||
@ -34,7 +37,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap);
|
||||
|
||||
var hudOverlay = new HUDOverlay(scoreProcessor, null, drawableRuleset, Array.Empty<Mod>())
|
||||
var hudOverlay = new HUDOverlay(drawableRuleset, Array.Empty<Mod>())
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
@ -27,6 +27,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Cached]
|
||||
private ScoreProcessor scoreProcessor = new ScoreProcessor();
|
||||
|
||||
[Cached(typeof(HealthProcessor))]
|
||||
private HealthProcessor healthProcessor = new DrainingHealthProcessor(0);
|
||||
|
||||
private IEnumerable<HUDOverlay> hudOverlays => CreatedDrawables.OfType<HUDOverlay>();
|
||||
|
||||
// best way to check without exposing.
|
||||
@ -76,7 +79,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
SetContents(() =>
|
||||
{
|
||||
hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty<Mod>());
|
||||
hudOverlay = new HUDOverlay(null, Array.Empty<Mod>());
|
||||
|
||||
// Add any key just to display the key counter visually.
|
||||
hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
|
||||
|
@ -4,11 +4,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
@ -19,6 +22,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
|
||||
|
||||
[Cached(typeof(HealthProcessor))]
|
||||
private HealthProcessor healthProcessor = new DrainingHealthProcessor(0);
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetUpSteps()
|
||||
{
|
||||
@ -28,8 +34,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
});
|
||||
AddStep(@"Reset all", delegate
|
||||
{
|
||||
foreach (var s in healthDisplays)
|
||||
s.Current.Value = 1;
|
||||
healthProcessor.Health.Value = 1;
|
||||
});
|
||||
}
|
||||
|
||||
@ -38,23 +43,21 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
AddRepeatStep(@"decrease hp", delegate
|
||||
{
|
||||
foreach (var healthDisplay in healthDisplays)
|
||||
healthDisplay.Current.Value -= 0.08f;
|
||||
healthProcessor.Health.Value -= 0.08f;
|
||||
}, 10);
|
||||
|
||||
AddRepeatStep(@"increase hp without flash", delegate
|
||||
{
|
||||
foreach (var healthDisplay in healthDisplays)
|
||||
healthDisplay.Current.Value += 0.1f;
|
||||
healthProcessor.Health.Value += 0.1f;
|
||||
}, 3);
|
||||
|
||||
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;
|
||||
healthDisplay.Flash(new JudgementResult(null, new OsuJudgement()));
|
||||
}
|
||||
Type = HitResult.Perfect
|
||||
});
|
||||
}, 3);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,240 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics.Containers.Markdown;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Tests.Visual.UserInterface
|
||||
{
|
||||
public class TestSceneOsuMarkdownContainer : OsuTestScene
|
||||
{
|
||||
private OsuMarkdownContainer markdownContainer;
|
||||
|
||||
[Cached]
|
||||
private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Orange);
|
||||
|
||||
[SetUp]
|
||||
public void Setup() => Schedule(() =>
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = overlayColour.Background5,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new BasicScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(20),
|
||||
Child = markdownContainer = new OsuMarkdownContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestEmphases()
|
||||
{
|
||||
AddStep("Emphases", () =>
|
||||
{
|
||||
markdownContainer.Text = @"_italic with underscore_
|
||||
*italic with asterisk*
|
||||
__bold with underscore__
|
||||
**bold with asterisk**
|
||||
*__italic with asterisk, bold with underscore__*
|
||||
_**italic with underscore, bold with asterisk**_";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHeading()
|
||||
{
|
||||
AddStep("Add Heading", () =>
|
||||
{
|
||||
markdownContainer.Text = @"# Header 1
|
||||
## Header 2
|
||||
### Header 3
|
||||
#### Header 4
|
||||
##### Header 5";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLink()
|
||||
{
|
||||
AddStep("Add Link", () =>
|
||||
{
|
||||
markdownContainer.Text = "[Welcome to osu!](https://osu.ppy.sh)";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLinkWithInlineText()
|
||||
{
|
||||
AddStep("Add Link with inline text", () =>
|
||||
{
|
||||
markdownContainer.Text = "Hey, [welcome to osu!](https://osu.ppy.sh) Please enjoy the game.";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestInlineCode()
|
||||
{
|
||||
AddStep("Add inline code", () =>
|
||||
{
|
||||
markdownContainer.Text = "This is `inline code` text";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestParagraph()
|
||||
{
|
||||
AddStep("Add paragraph", () =>
|
||||
{
|
||||
markdownContainer.Text = @"first paragraph
|
||||
|
||||
second paragraph
|
||||
|
||||
third paragraph";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFencedCodeBlock()
|
||||
{
|
||||
AddStep("Add Code Block", () =>
|
||||
{
|
||||
markdownContainer.Text = @"```markdown
|
||||
# Markdown code block
|
||||
|
||||
This is markdown code block.
|
||||
```";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSeparator()
|
||||
{
|
||||
AddStep("Add Seperator", () =>
|
||||
{
|
||||
markdownContainer.Text = @"Line above
|
||||
|
||||
---
|
||||
|
||||
Line below";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestQuote()
|
||||
{
|
||||
AddStep("Add quote", () =>
|
||||
{
|
||||
markdownContainer.Text =
|
||||
@"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTable()
|
||||
{
|
||||
AddStep("Add Table", () =>
|
||||
{
|
||||
markdownContainer.Text =
|
||||
@"| Left Aligned | Center Aligned | Right Aligned |
|
||||
| :------------------- | :--------------------: | ---------------------:|
|
||||
| Long Align Left Text | Long Align Center Text | Long Align Right Text |
|
||||
| Align Left | Align Center | Align Right |
|
||||
| Left | Center | Right |";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUnorderedList()
|
||||
{
|
||||
AddStep("Add Unordered List", () =>
|
||||
{
|
||||
markdownContainer.Text = @"- First item level 1
|
||||
- Second item level 1
|
||||
- First item level 2
|
||||
- First item level 3
|
||||
- Second item level 3
|
||||
- Third item level 3
|
||||
- First item level 4
|
||||
- Second item level 4
|
||||
- Third item level 4
|
||||
- Second item level 2
|
||||
- Third item level 2
|
||||
- Third item level 1";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOrderedList()
|
||||
{
|
||||
AddStep("Add Ordered List", () =>
|
||||
{
|
||||
markdownContainer.Text = @"1. First item level 1
|
||||
2. Second item level 1
|
||||
1. First item level 2
|
||||
1. First item level 3
|
||||
2. Second item level 3
|
||||
3. Third item level 3
|
||||
1. First item level 4
|
||||
2. Second item level 4
|
||||
3. Third item level 4
|
||||
2. Second item level 2
|
||||
3. Third item level 2
|
||||
3. Third item level 1";
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLongMixedList()
|
||||
{
|
||||
AddStep("Add long mixed list", () =>
|
||||
{
|
||||
markdownContainer.Text = @"1. The osu! World Cup is a country-based team tournament played on the osu! game mode.
|
||||
- While this competition is planned as a 4 versus 4 setup, this may change depending on the number of incoming registrations.
|
||||
2. Beatmap scoring is based on Score V2.
|
||||
3. The beatmaps for each round will be announced by the map selectors in advance on the Sunday before the actual matches take place. Only these beatmaps will be used during the respective matches.
|
||||
- One beatmap will be a tiebreaker beatmap. This beatmap will only be played in case of a tie. **The only exception to this is the Qualifiers pool.**
|
||||
4. The match schedule will be settled by the Tournament Management (see the [scheduling instructions](#scheduling-instructions)).
|
||||
5. If no staff or referee is available, the match will be postponed.
|
||||
6. Use of the Visual Settings to alter background dim or disable beatmap elements like storyboards and skins are allowed.
|
||||
7. If the beatmap ends in a draw, the map will be nullified and replayed.
|
||||
8. If a player disconnects, their scores will not be counted towards their team's total.
|
||||
- Disconnects within 30 seconds or 25% of the beatmap length (whichever happens first) after beatmap begin can be aborted and/or rematched. This is up to the referee's discretion.
|
||||
9. Beatmaps cannot be reused in the same match unless the map was nullified.
|
||||
10. If less than the minimum required players attend, the maximum time the match can be postponed is 10 minutes.
|
||||
11. Exchanging players during a match is allowed without limitations.
|
||||
- **If a map rematch is required, exchanging players is not allowed. With the referee's discretion, an exception can be made if the previous roster is unavailable to play.**
|
||||
12. Lag is not a valid reason to nullify a beatmap.
|
||||
13. All players are supposed to keep the match running fluently and without delays. Penalties can be issued to the players if they cause excessive match delays.
|
||||
14. If a player disconnects between maps and the team cannot provide a replacement, the match can be delayed 10 minutes at maximum.
|
||||
15. All players and referees must be treated with respect. Instructions of the referees and tournament Management are to be followed. Decisions labeled as final are not to be objected.
|
||||
16. Disrupting the match by foul play, insulting and provoking other players or referees, delaying the match or other deliberate inappropriate misbehavior is strictly prohibited.
|
||||
17. The multiplayer chatrooms are subject to the [osu! community rules](/wiki/Rules).
|
||||
- Breaking the chat rules will result in a silence. Silenced players can not participate in multiplayer matches and must be exchanged for the time being.
|
||||
18. **The seeding method will be revealed after all the teams have played their Qualifier rounds.**
|
||||
19. Unexpected incidents are handled by the tournament management. Referees may allow higher tolerance depending on the circumstances. This is up to their discretion.
|
||||
20. Penalties for violating the tournament rules may include:
|
||||
- Exclusion of specific players for one beatmap
|
||||
- Exclusion of specific players for an entire match
|
||||
- Declaring the match as Lost by Default
|
||||
- Disqualification from the entire tournament
|
||||
- Disqualification from the current and future official tournaments until appealed
|
||||
- Any modification of these rules will be announced.";
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
// 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 Markdig;
|
||||
using Markdig.Extensions.AutoIdentifiers;
|
||||
using Markdig.Extensions.Tables;
|
||||
using Markdig.Extensions.Yaml;
|
||||
using Markdig.Syntax;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownContainer : MarkdownContainer
|
||||
{
|
||||
public OsuMarkdownContainer()
|
||||
{
|
||||
LineSpacing = 21;
|
||||
}
|
||||
|
||||
protected override void AddMarkdownComponent(IMarkdownObject markdownObject, FillFlowContainer container, int level)
|
||||
{
|
||||
switch (markdownObject)
|
||||
{
|
||||
case YamlFrontMatterBlock _:
|
||||
// Don't parse YAML Frontmatter
|
||||
break;
|
||||
|
||||
case ListItemBlock listItemBlock:
|
||||
var isOrdered = ((ListBlock)listItemBlock.Parent).IsOrdered;
|
||||
var childContainer = CreateListItem(listItemBlock, level, isOrdered);
|
||||
container.Add(childContainer);
|
||||
foreach (var single in listItemBlock)
|
||||
base.AddMarkdownComponent(single, childContainer.Content, level);
|
||||
break;
|
||||
|
||||
default:
|
||||
base.AddMarkdownComponent(markdownObject, container, level);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override SpriteText CreateSpriteText() => new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.GetFont(size: 14),
|
||||
};
|
||||
|
||||
public override MarkdownTextFlowContainer CreateTextFlow() => new OsuMarkdownTextFlowContainer();
|
||||
|
||||
protected override MarkdownHeading CreateHeading(HeadingBlock headingBlock) => new OsuMarkdownHeading(headingBlock);
|
||||
|
||||
protected override MarkdownFencedCodeBlock CreateFencedCodeBlock(FencedCodeBlock fencedCodeBlock) => new OsuMarkdownFencedCodeBlock(fencedCodeBlock);
|
||||
|
||||
protected override MarkdownSeparator CreateSeparator(ThematicBreakBlock thematicBlock) => new OsuMarkdownSeparator();
|
||||
|
||||
protected override MarkdownQuoteBlock CreateQuoteBlock(QuoteBlock quoteBlock) => new OsuMarkdownQuoteBlock(quoteBlock);
|
||||
|
||||
protected override MarkdownTable CreateTable(Table table) => new OsuMarkdownTable(table);
|
||||
|
||||
protected override MarkdownList CreateList(ListBlock listBlock) => new MarkdownList
|
||||
{
|
||||
Padding = new MarginPadding(0)
|
||||
};
|
||||
|
||||
protected virtual OsuMarkdownListItem CreateListItem(ListItemBlock listItemBlock, int level, bool isOrdered)
|
||||
{
|
||||
if (isOrdered)
|
||||
return new OsuMarkdownOrderedListItem(listItemBlock.Order);
|
||||
|
||||
return new OsuMarkdownUnorderedListItem(level);
|
||||
}
|
||||
|
||||
protected override MarkdownPipeline CreateBuilder()
|
||||
=> new MarkdownPipelineBuilder().UseAutoIdentifiers(AutoIdentifierOptions.GitHub)
|
||||
.UseEmojiAndSmiley()
|
||||
.UseYamlFrontMatter()
|
||||
.UseAdvancedExtensions().Build();
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
// 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 Markdig.Syntax;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownFencedCodeBlock : MarkdownFencedCodeBlock
|
||||
{
|
||||
// TODO : change to monospace font for this component
|
||||
public OsuMarkdownFencedCodeBlock(FencedCodeBlock fencedCodeBlock)
|
||||
: base(fencedCodeBlock)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Drawable CreateBackground() => new CodeBlockBackground();
|
||||
|
||||
public override MarkdownTextFlowContainer CreateTextFlow() => new CodeBlockTextFlowContainer();
|
||||
|
||||
private class CodeBlockBackground : Box
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Colour = colourProvider.Background6;
|
||||
}
|
||||
}
|
||||
|
||||
private class CodeBlockTextFlowContainer : OsuMarkdownTextFlowContainer
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
Colour = colourProvider.Light1;
|
||||
Margin = new MarginPadding(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
75
osu.Game/Graphics/Containers/Markdown/OsuMarkdownHeading.cs
Normal file
75
osu.Game/Graphics/Containers/Markdown/OsuMarkdownHeading.cs
Normal file
@ -0,0 +1,75 @@
|
||||
// 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 Markdig.Syntax;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownHeading : MarkdownHeading
|
||||
{
|
||||
private readonly int level;
|
||||
|
||||
public OsuMarkdownHeading(HeadingBlock headingBlock)
|
||||
: base(headingBlock)
|
||||
{
|
||||
level = headingBlock.Level;
|
||||
}
|
||||
|
||||
public override MarkdownTextFlowContainer CreateTextFlow() => new HeadingTextFlowContainer
|
||||
{
|
||||
Weight = GetFontWeightByLevel(level),
|
||||
};
|
||||
|
||||
protected override float GetFontSizeByLevel(int level)
|
||||
{
|
||||
// Reference for this font size
|
||||
// https://github.com/ppy/osu-web/blob/376cac43a051b9c85ce95e2c446099be187b3e45/resources/assets/less/bem/osu-md.less#L9
|
||||
// https://github.com/ppy/osu-web/blob/376cac43a051b9c85ce95e2c446099be187b3e45/resources/assets/less/variables.less#L161
|
||||
const float base_font_size = 14;
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case 1:
|
||||
return 30 / base_font_size;
|
||||
|
||||
case 2:
|
||||
return 26 / base_font_size;
|
||||
|
||||
case 3:
|
||||
return 20 / base_font_size;
|
||||
|
||||
case 4:
|
||||
return 18 / base_font_size;
|
||||
|
||||
case 5:
|
||||
return 16 / base_font_size;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual FontWeight GetFontWeightByLevel(int level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
return FontWeight.SemiBold;
|
||||
|
||||
default:
|
||||
return FontWeight.Bold;
|
||||
}
|
||||
}
|
||||
|
||||
private class HeadingTextFlowContainer : OsuMarkdownTextFlowContainer
|
||||
{
|
||||
public FontWeight Weight { get; set; }
|
||||
|
||||
protected override SpriteText CreateSpriteText() => base.CreateSpriteText().With(t => t.Font = t.Font.With(weight: Weight));
|
||||
}
|
||||
}
|
||||
}
|
48
osu.Game/Graphics/Containers/Markdown/OsuMarkdownLinkText.cs
Normal file
48
osu.Game/Graphics/Containers/Markdown/OsuMarkdownLinkText.cs
Normal file
@ -0,0 +1,48 @@
|
||||
// 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 Markdig.Syntax.Inlines;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownLinkText : MarkdownLinkText
|
||||
{
|
||||
[Resolved]
|
||||
private OverlayColourProvider colourProvider { get; set; }
|
||||
|
||||
private SpriteText spriteText;
|
||||
|
||||
public OsuMarkdownLinkText(string text, LinkInline linkInline)
|
||||
: base(text, linkInline)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
spriteText.Colour = colourProvider.Light2;
|
||||
}
|
||||
|
||||
public override SpriteText CreateSpriteText()
|
||||
{
|
||||
return spriteText = base.CreateSpriteText();
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
spriteText.Colour = colourProvider.Light1;
|
||||
return base.OnHover(e);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
spriteText.Colour = colourProvider.Light2;
|
||||
base.OnHoverLost(e);
|
||||
}
|
||||
}
|
||||
}
|
44
osu.Game/Graphics/Containers/Markdown/OsuMarkdownListItem.cs
Normal file
44
osu.Game/Graphics/Containers/Markdown/OsuMarkdownListItem.cs
Normal file
@ -0,0 +1,44 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public abstract class OsuMarkdownListItem : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private IMarkdownTextComponent parentTextComponent { get; set; }
|
||||
|
||||
public FillFlowContainer Content { get; private set; }
|
||||
|
||||
protected OsuMarkdownListItem()
|
||||
{
|
||||
AutoSizeAxes = Axes.Y;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
CreateMarker(),
|
||||
Content = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(10, 10),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected virtual SpriteText CreateMarker() => parentTextComponent.CreateSpriteText();
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownOrderedListItem : OsuMarkdownListItem
|
||||
{
|
||||
private const float left_padding = 30;
|
||||
|
||||
private readonly int order;
|
||||
|
||||
public OsuMarkdownOrderedListItem(int order)
|
||||
{
|
||||
this.order = order;
|
||||
Padding = new MarginPadding { Left = left_padding };
|
||||
}
|
||||
|
||||
protected override SpriteText CreateMarker() => base.CreateMarker().With(t =>
|
||||
{
|
||||
t.X = -left_padding;
|
||||
t.Text = $"{order}.";
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
// 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 Markdig.Syntax;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownQuoteBlock : MarkdownQuoteBlock
|
||||
{
|
||||
public OsuMarkdownQuoteBlock(QuoteBlock quoteBlock)
|
||||
: base(quoteBlock)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Drawable CreateBackground() => new QuoteBackground();
|
||||
|
||||
public override MarkdownTextFlowContainer CreateTextFlow()
|
||||
{
|
||||
return base.CreateTextFlow().With(f => f.Margin = new MarginPadding
|
||||
{
|
||||
Vertical = 10,
|
||||
Horizontal = 20,
|
||||
});
|
||||
}
|
||||
|
||||
private class QuoteBackground : Box
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft;
|
||||
Origin = Anchor.CentreLeft;
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Width = 2;
|
||||
Colour = colourProvider.Content2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownSeparator : MarkdownSeparator
|
||||
{
|
||||
protected override Drawable CreateSeparator() => new Separator();
|
||||
|
||||
private class Separator : Box
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 1;
|
||||
Colour = colourProvider.Background3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
osu.Game/Graphics/Containers/Markdown/OsuMarkdownTable.cs
Normal file
18
osu.Game/Graphics/Containers/Markdown/OsuMarkdownTable.cs
Normal file
@ -0,0 +1,18 @@
|
||||
// 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 Markdig.Extensions.Tables;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownTable : MarkdownTable
|
||||
{
|
||||
public OsuMarkdownTable(Table table)
|
||||
: base(table)
|
||||
{
|
||||
}
|
||||
|
||||
protected override MarkdownTableCell CreateTableCell(TableCell cell, TableColumnDefinition definition, bool isHeading) => new OsuMarkdownTableCell(cell, definition, isHeading);
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
// 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 Markdig.Extensions.Tables;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownTableCell : MarkdownTableCell
|
||||
{
|
||||
private readonly bool isHeading;
|
||||
|
||||
public OsuMarkdownTableCell(TableCell cell, TableColumnDefinition definition, bool isHeading)
|
||||
: base(cell, definition)
|
||||
{
|
||||
this.isHeading = isHeading;
|
||||
Masking = false;
|
||||
BorderThickness = 0;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
AddInternal(CreateBorder(isHeading));
|
||||
}
|
||||
|
||||
public override MarkdownTextFlowContainer CreateTextFlow() => new TableCellTextFlowContainer
|
||||
{
|
||||
Weight = isHeading ? FontWeight.Bold : FontWeight.Regular,
|
||||
Padding = new MarginPadding(10),
|
||||
};
|
||||
|
||||
protected virtual Box CreateBorder(bool isHeading)
|
||||
{
|
||||
if (isHeading)
|
||||
return new TableHeadBorder();
|
||||
|
||||
return new TableBodyBorder();
|
||||
}
|
||||
|
||||
private class TableHeadBorder : Box
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
Colour = colourProvider.Background3;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 2;
|
||||
Anchor = Anchor.BottomLeft;
|
||||
Origin = Anchor.BottomLeft;
|
||||
}
|
||||
}
|
||||
|
||||
private class TableBodyBorder : Box
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
Colour = colourProvider.Background4;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 1;
|
||||
}
|
||||
}
|
||||
|
||||
private class TableCellTextFlowContainer : OsuMarkdownTextFlowContainer
|
||||
{
|
||||
public FontWeight Weight { get; set; }
|
||||
|
||||
protected override SpriteText CreateSpriteText() => base.CreateSpriteText().With(t => t.Font = t.Font.With(weight: Weight));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// 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 Markdig.Syntax.Inlines;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers.Markdown;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownTextFlowContainer : MarkdownTextFlowContainer
|
||||
{
|
||||
[Resolved]
|
||||
private OverlayColourProvider colourProvider { get; set; }
|
||||
|
||||
protected override SpriteText CreateSpriteText() => new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.GetFont(size: 14),
|
||||
};
|
||||
|
||||
protected override void AddLinkText(string text, LinkInline linkInline)
|
||||
=> AddDrawable(new OsuMarkdownLinkText(text, linkInline));
|
||||
|
||||
// TODO : Add background (colour B6) and change font to monospace
|
||||
protected override void AddCodeInLine(CodeInline codeInline)
|
||||
=> AddText(codeInline.Content, t => { t.Colour = colourProvider.Light1; });
|
||||
|
||||
protected override SpriteText CreateEmphasisedSpriteText(bool bold, bool italic)
|
||||
=> CreateSpriteText().With(t => t.Font = t.Font.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, italics: italic));
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Graphics.Containers.Markdown
|
||||
{
|
||||
public class OsuMarkdownUnorderedListItem : OsuMarkdownListItem
|
||||
{
|
||||
private const float left_padding = 20;
|
||||
|
||||
private readonly int level;
|
||||
|
||||
public OsuMarkdownUnorderedListItem(int level)
|
||||
{
|
||||
this.level = level;
|
||||
|
||||
Padding = new MarginPadding { Left = left_padding };
|
||||
}
|
||||
|
||||
protected override SpriteText CreateMarker() => base.CreateMarker().With(t =>
|
||||
{
|
||||
t.Text = GetTextMarker(level);
|
||||
t.Font = t.Font.With(size: t.Font.Size / 2);
|
||||
t.Origin = Anchor.Centre;
|
||||
t.X = -left_padding / 2;
|
||||
t.Y = t.Font.Size;
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Get text marker based on <paramref name="level"/>
|
||||
/// </summary>
|
||||
/// <param name="level">The markdown level of current list item.</param>
|
||||
/// <returns>The marker string of this list item</returns>
|
||||
protected virtual string GetTextMarker(int level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case 1:
|
||||
return "●";
|
||||
|
||||
case 2:
|
||||
return "○";
|
||||
|
||||
default:
|
||||
return "■";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +1,36 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Replays
|
||||
{
|
||||
public abstract class AutoGenerator : IAutoGenerator
|
||||
public abstract class AutoGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates the auto replay and returns it.
|
||||
/// Every subclass of OsuAutoGeneratorBase should implement this!
|
||||
/// The default duration of a key press in milliseconds.
|
||||
/// </summary>
|
||||
public abstract Replay Generate();
|
||||
|
||||
#region Parameters
|
||||
public const double KEY_UP_DELAY = 50;
|
||||
|
||||
/// <summary>
|
||||
/// The beatmap we're making.
|
||||
/// The beatmap the autoplay is generated for.
|
||||
/// </summary>
|
||||
protected IBeatmap Beatmap;
|
||||
|
||||
#endregion
|
||||
protected IBeatmap Beatmap { get; }
|
||||
|
||||
protected AutoGenerator(IBeatmap beatmap)
|
||||
{
|
||||
Beatmap = beatmap;
|
||||
}
|
||||
|
||||
#region Constants
|
||||
|
||||
// Shared amongst all modes
|
||||
public const double KEY_UP_DELAY = 50;
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Generate the replay of the autoplay.
|
||||
/// </summary>
|
||||
public abstract Replay Generate();
|
||||
|
||||
protected virtual HitObject GetNextObject(int currentIndex)
|
||||
{
|
||||
@ -44,4 +40,37 @@ namespace osu.Game.Rulesets.Replays
|
||||
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;
|
||||
}
|
||||
|
||||
public override void Flash(JudgementResult result) => Scheduler.AddOnce(flash);
|
||||
protected override void Flash(JudgementResult result) => Scheduler.AddOnce(flash);
|
||||
|
||||
private void flash()
|
||||
{
|
||||
|
@ -39,7 +39,6 @@ namespace osu.Game.Screens.Play.HUD
|
||||
private readonly Container boxes;
|
||||
|
||||
private Bindable<bool> fadePlayfieldWhenHealthLow;
|
||||
private HealthProcessor healthProcessor;
|
||||
|
||||
public FailingLayer()
|
||||
{
|
||||
@ -88,18 +87,10 @@ namespace osu.Game.Screens.Play.HUD
|
||||
updateState();
|
||||
}
|
||||
|
||||
public override void BindHealthProcessor(HealthProcessor processor)
|
||||
{
|
||||
base.BindHealthProcessor(processor);
|
||||
|
||||
healthProcessor = processor;
|
||||
updateState();
|
||||
}
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
@ -11,26 +12,43 @@ namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
/// <summary>
|
||||
/// 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>
|
||||
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)
|
||||
{
|
||||
MinValue = 0,
|
||||
MaxValue = 1
|
||||
};
|
||||
|
||||
public virtual void Flash(JudgementResult result)
|
||||
protected virtual void Flash(JudgementResult result)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bind the tracked fields of <see cref="HealthProcessor"/> to this health display.
|
||||
/// </summary>
|
||||
public virtual void BindHealthProcessor(HealthProcessor processor)
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
||||
|
||||
@ -22,17 +21,11 @@ namespace osu.Game.Screens.Play.HUD
|
||||
|
||||
private readonly HitWindows hitWindows;
|
||||
|
||||
private readonly ScoreProcessor processor;
|
||||
|
||||
public HitErrorDisplay(ScoreProcessor processor, HitWindows hitWindows)
|
||||
public HitErrorDisplay(HitWindows hitWindows)
|
||||
{
|
||||
this.processor = processor;
|
||||
this.hitWindows = hitWindows;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
if (processor != null)
|
||||
processor.NewJudgement += onNewJudgement;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -47,15 +40,6 @@ namespace osu.Game.Screens.Play.HUD
|
||||
type.BindValueChanged(typeChanged, true);
|
||||
}
|
||||
|
||||
private void onNewJudgement(JudgementResult result)
|
||||
{
|
||||
if (result.HitObject.HitWindows.WindowFor(HitResult.Miss) == 0)
|
||||
return;
|
||||
|
||||
foreach (var c in Children)
|
||||
c.OnNewJudgement(result);
|
||||
}
|
||||
|
||||
private void typeChanged(ValueChangedEvent<ScoreMeterType> type)
|
||||
{
|
||||
Children.ForEach(c => c.FadeOut(fade_duration, Easing.OutQuint));
|
||||
@ -139,13 +123,5 @@ namespace osu.Game.Screens.Play.HUD
|
||||
Add(display);
|
||||
display.FadeInFromZero(fade_duration, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (processor != null)
|
||||
processor.NewJudgement -= onNewJudgement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
||||
|
||||
private const int max_concurrent_judgements = 50;
|
||||
|
||||
public override void OnNewJudgement(JudgementResult judgement)
|
||||
protected override void OnNewJudgement(JudgementResult judgement)
|
||||
{
|
||||
if (!judgement.IsHit)
|
||||
return;
|
||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
||||
InternalChild = judgementsFlow = new JudgementFlow();
|
||||
}
|
||||
|
||||
public override void OnNewJudgement(JudgementResult judgement) => judgementsFlow.Push(GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset)));
|
||||
protected override void OnNewJudgement(JudgementResult judgement) => judgementsFlow.Push(GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset)));
|
||||
|
||||
private class JudgementFlow : FillFlowContainer<HitErrorCircle>
|
||||
{
|
||||
|
@ -14,6 +14,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
||||
{
|
||||
protected readonly HitWindows HitWindows;
|
||||
|
||||
[Resolved]
|
||||
private ScoreProcessor processor { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
@ -22,7 +25,22 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
||||
HitWindows = hitWindows;
|
||||
}
|
||||
|
||||
public abstract void OnNewJudgement(JudgementResult judgement);
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
processor.NewJudgement += onNewJudgement;
|
||||
}
|
||||
|
||||
private void onNewJudgement(JudgementResult result)
|
||||
{
|
||||
if (result.HitObject.HitWindows?.WindowFor(HitResult.Miss) == 0)
|
||||
return;
|
||||
|
||||
OnNewJudgement(result);
|
||||
}
|
||||
|
||||
protected abstract void OnNewJudgement(JudgementResult judgement);
|
||||
|
||||
protected Color4 GetColourForHitResult(HitResult result)
|
||||
{
|
||||
@ -47,5 +65,13 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
||||
return colours.BlueLight;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (processor != null)
|
||||
processor.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.
|
||||
// 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;
|
||||
|
||||
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()
|
||||
: base(new HUDSkinComponent(HUDSkinComponents.HealthDisplay), _ => new DefaultHealthDisplay())
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ using osu.Game.Input.Bindings;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osuTK;
|
||||
@ -39,15 +38,11 @@ namespace osu.Game.Screens.Play
|
||||
public readonly SkinnableHealthDisplay HealthDisplay;
|
||||
public readonly SongProgress Progress;
|
||||
public readonly ModDisplay ModDisplay;
|
||||
public readonly HitErrorDisplay HitErrorDisplay;
|
||||
public readonly HoldForMenuButton HoldToQuit;
|
||||
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
|
||||
public readonly FailingLayer FailingLayer;
|
||||
|
||||
public Bindable<bool> ShowHealthbar = new Bindable<bool>(true);
|
||||
|
||||
private readonly ScoreProcessor scoreProcessor;
|
||||
private readonly HealthProcessor healthProcessor;
|
||||
private readonly DrawableRuleset drawableRuleset;
|
||||
private readonly IReadOnlyList<Mod> mods;
|
||||
|
||||
@ -75,10 +70,8 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private IEnumerable<Drawable> hideTargets => new Drawable[] { visibilityContainer, KeyCounter, topRightElements };
|
||||
|
||||
public HUDOverlay(ScoreProcessor scoreProcessor, HealthProcessor healthProcessor, DrawableRuleset drawableRuleset, IReadOnlyList<Mod> mods)
|
||||
public HUDOverlay(DrawableRuleset drawableRuleset, IReadOnlyList<Mod> mods)
|
||||
{
|
||||
this.scoreProcessor = scoreProcessor;
|
||||
this.healthProcessor = healthProcessor;
|
||||
this.drawableRuleset = drawableRuleset;
|
||||
this.mods = mods;
|
||||
|
||||
@ -86,7 +79,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
FailingLayer = CreateFailingLayer(),
|
||||
CreateFailingLayer(),
|
||||
visibilityContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -106,7 +99,7 @@ namespace osu.Game.Screens.Play
|
||||
AccuracyCounter = CreateAccuracyCounter(),
|
||||
ScoreCounter = CreateScoreCounter(),
|
||||
CreateComboCounter(),
|
||||
HitErrorDisplay = CreateHitErrorDisplayOverlay(),
|
||||
CreateHitErrorDisplayOverlay(),
|
||||
}
|
||||
},
|
||||
},
|
||||
@ -158,12 +151,6 @@ namespace osu.Game.Screens.Play
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
|
||||
{
|
||||
if (scoreProcessor != null)
|
||||
BindScoreProcessor(scoreProcessor);
|
||||
|
||||
if (healthProcessor != null)
|
||||
BindHealthProcessor(healthProcessor);
|
||||
|
||||
if (drawableRuleset != null)
|
||||
{
|
||||
BindDrawableRuleset(drawableRuleset);
|
||||
@ -314,28 +301,10 @@ namespace osu.Game.Screens.Play
|
||||
AutoSizeAxes = Axes.Both,
|
||||
};
|
||||
|
||||
protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset?.FirstAvailableHitWindows);
|
||||
protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(drawableRuleset?.FirstAvailableHitWindows);
|
||||
|
||||
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)
|
||||
{
|
||||
switch (action)
|
||||
|
@ -208,6 +208,8 @@ namespace osu.Game.Screens.Play
|
||||
HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime);
|
||||
HealthProcessor.ApplyBeatmap(playableBeatmap);
|
||||
|
||||
dependencies.CacheAs(HealthProcessor);
|
||||
|
||||
if (!ScoreProcessor.Mode.Disabled)
|
||||
config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
|
||||
|
||||
@ -343,7 +345,7 @@ namespace osu.Game.Screens.Play
|
||||
// display the cursor above some HUD elements.
|
||||
DrawableRuleset.Cursor?.CreateProxy() ?? new Container(),
|
||||
DrawableRuleset.ResumeOverlay?.CreateProxy() ?? new Container(),
|
||||
HUDOverlay = new HUDOverlay(ScoreProcessor, HealthProcessor, DrawableRuleset, Mods.Value)
|
||||
HUDOverlay = new HUDOverlay(DrawableRuleset, Mods.Value)
|
||||
{
|
||||
HoldToQuit =
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class LegacyHealthDisplay : CompositeDrawable, IHealthDisplay, ISkinnableComponent
|
||||
public class LegacyHealthDisplay : HealthDisplay
|
||||
{
|
||||
private const double epic_cutoff = 0.5;
|
||||
|
||||
@ -28,12 +28,6 @@ namespace osu.Game.Skinning
|
||||
|
||||
private bool isNewStyle;
|
||||
|
||||
public Bindable<double> Current { get; } = new BindableDouble(1)
|
||||
{
|
||||
MinValue = 0,
|
||||
MaxValue = 1
|
||||
};
|
||||
|
||||
public LegacyHealthDisplay(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);
|
||||
}
|
||||
|
||||
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}");
|
||||
|
||||
@ -254,7 +248,7 @@ namespace osu.Game.Skinning
|
||||
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>();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user