Merge branch 'master' into hide-hud-during-break-time

This commit is contained in:
Dean Herbert
2020-10-20 14:19:04 +09:00
1030 changed files with 27160 additions and 7705 deletions

View File

@ -10,7 +10,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Mods;
@ -22,16 +21,18 @@ using osuTK.Input;
namespace osu.Game.Screens.Play
{
[Cached]
public class HUDOverlay : Container
{
private const float fade_duration = 400;
private const Easing fade_easing = Easing.Out;
public const float FADE_DURATION = 400;
public const Easing FADE_EASING = Easing.Out;
public readonly KeyCounterDisplay KeyCounter;
public readonly RollingCounter<int> ComboCounter;
public readonly ScoreCounter ScoreCounter;
public readonly RollingCounter<double> AccuracyCounter;
public readonly HealthDisplay HealthDisplay;
public readonly SkinnableComboCounter ComboCounter;
public readonly SkinnableScoreCounter ScoreCounter;
public readonly SkinnableAccuracyCounter AccuracyCounter;
public readonly SkinnableHealthDisplay HealthDisplay;
public readonly SongProgress Progress;
public readonly ModDisplay ModDisplay;
public readonly HitErrorDisplay HitErrorDisplay;
@ -61,7 +62,8 @@ namespace osu.Game.Screens.Play
public Action<double> RequestSeek;
private readonly Container topScoreContainer;
private readonly FillFlowContainer bottomRightElements;
private readonly FillFlowContainer topRightElements;
internal readonly IBindable<bool> IsBreakTime = new Bindable<bool>();
@ -82,35 +84,61 @@ namespace osu.Game.Screens.Play
visibilityContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Child = new GridContainer
{
RelativeSizeAxes = Axes.Both,
Content = new[]
{
new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
HealthDisplay = CreateHealthDisplay(),
AccuracyCounter = CreateAccuracyCounter(),
ScoreCounter = CreateScoreCounter(),
ComboCounter = CreateComboCounter(),
HitErrorDisplay = CreateHitErrorDisplayOverlay(),
}
},
},
new Drawable[]
{
Progress = CreateProgress(),
}
},
RowDimensions = new[]
{
new Dimension(),
new Dimension(GridSizeMode.AutoSize)
}
},
},
topRightElements = new FillFlowContainer
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Margin = new MarginPadding(10),
Spacing = new Vector2(10),
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
HealthDisplay = CreateHealthDisplay(),
topScoreContainer = new Container
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
AccuracyCounter = CreateAccuracyCounter(),
ScoreCounter = CreateScoreCounter(),
ComboCounter = CreateComboCounter(),
},
},
Progress = CreateProgress(),
ModDisplay = CreateModsContainer(),
HitErrorDisplay = CreateHitErrorDisplayOverlay(),
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
}
},
new FillFlowContainer
bottomRightElements = new FillFlowContainer
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Position = -new Vector2(5, TwoLayerButton.SIZE_RETRACTED.Y),
Margin = new MarginPadding(10),
Spacing = new Vector2(10),
AutoSizeAxes = Axes.Both,
LayoutDuration = fade_duration / 2,
LayoutEasing = fade_easing,
LayoutDuration = FADE_DURATION / 2,
LayoutEasing = FADE_EASING,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
@ -163,21 +191,8 @@ namespace osu.Game.Screens.Play
{
base.LoadComplete();
ShowHud.BindValueChanged(visible => hideTargets.ForEach(d => d.FadeTo(visible.NewValue ? 1 : 0, fade_duration, fade_easing)));
ShowHealthbar.BindValueChanged(healthBar =>
{
if (healthBar.NewValue)
{
HealthDisplay.FadeIn(fade_duration, fade_easing);
topScoreContainer.MoveToY(30, fade_duration, fade_easing);
}
else
{
HealthDisplay.FadeOut(fade_duration, fade_easing);
topScoreContainer.MoveToY(0, fade_duration, fade_easing);
}
}, true);
ShowHealthbar.BindValueChanged(healthBar => HealthDisplay.FadeTo(healthBar.NewValue ? 1 : 0, FADE_DURATION, FADE_EASING), true);
ShowHud.BindValueChanged(visible => hideTargets.ForEach(d => d.FadeTo(visible.NewValue ? 1 : 0, FADE_DURATION, FADE_EASING)));
IsBreakTime.BindValueChanged(_ => updateVisibility());
configVisibilityMode.BindValueChanged(_ => updateVisibility(), true);
@ -185,6 +200,18 @@ namespace osu.Game.Screens.Play
replayLoaded.BindValueChanged(replayLoadedValueChanged, true);
}
protected override void Update()
{
base.Update();
// HACK: for now align with the accuracy counter.
// this is done for the sake of hacky legacy skins which extend the health bar to take up the full screen area.
// it only works with the default skin due to padding offsetting it *just enough* to coexist.
topRightElements.Y = ToLocalSpace(AccuracyCounter.Drawable.ScreenSpaceDrawQuad.BottomRight).Y;
bottomRightElements.Y = -Progress.Height;
}
private void updateVisibility()
{
if (ShowHud.Disabled)
@ -196,10 +223,16 @@ namespace osu.Game.Screens.Play
ShowHud.Value = false;
break;
case HUDVisibilityMode.DuringGameplay:
case HUDVisibilityMode.HideDuringBreaks:
// always show during replay as we want the seek bar to be visible.
ShowHud.Value = replayLoaded.Value || !IsBreakTime.Value;
break;
case HUDVisibilityMode.HideDuringGameplay:
// always show during replay as we want the seek bar to be visible.
ShowHud.Value = replayLoaded.Value || IsBreakTime.Value;
break;
case HUDVisibilityMode.Always:
ShowHud.Value = true;
break;
@ -246,7 +279,7 @@ namespace osu.Game.Screens.Play
case Key.Tab:
configVisibilityMode.Value = configVisibilityMode.Value != HUDVisibilityMode.Never
? HUDVisibilityMode.Never
: HUDVisibilityMode.DuringGameplay;
: HUDVisibilityMode.HideDuringGameplay;
return true;
}
}
@ -254,37 +287,13 @@ namespace osu.Game.Screens.Play
return base.OnKeyDown(e);
}
protected virtual RollingCounter<double> CreateAccuracyCounter() => new PercentageCounter
{
TextSize = 20,
BypassAutoSizeAxes = Axes.X,
Anchor = Anchor.TopLeft,
Origin = Anchor.TopRight,
Margin = new MarginPadding { Top = 5, Right = 20 },
};
protected virtual SkinnableAccuracyCounter CreateAccuracyCounter() => new SkinnableAccuracyCounter();
protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
{
TextSize = 40,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
};
protected virtual SkinnableScoreCounter CreateScoreCounter() => new SkinnableScoreCounter();
protected virtual RollingCounter<int> CreateComboCounter() => new SimpleComboCounter
{
TextSize = 20,
BypassAutoSizeAxes = Axes.X,
Anchor = Anchor.TopRight,
Origin = Anchor.TopLeft,
Margin = new MarginPadding { Top = 5, Left = 20 },
};
protected virtual SkinnableComboCounter CreateComboCounter() => new SkinnableComboCounter();
protected virtual HealthDisplay CreateHealthDisplay() => new StandardHealthDisplay
{
Size = new Vector2(1, 5),
RelativeSizeAxes = Axes.X,
Margin = new MarginPadding { Top = 20 }
};
protected virtual SkinnableHealthDisplay CreateHealthDisplay() => new SkinnableHealthDisplay();
protected virtual FailingLayer CreateFailingLayer() => new FailingLayer
{
@ -295,7 +304,6 @@ namespace osu.Game.Screens.Play
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Margin = new MarginPadding(10),
};
protected virtual SongProgress CreateProgress() => new SongProgress
@ -316,7 +324,6 @@ namespace osu.Game.Screens.Play
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = 20, Right = 20 },
};
protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset?.FirstAvailableHitWindows);
@ -329,8 +336,14 @@ namespace osu.Game.Screens.Play
AccuracyCounter?.Current.BindTo(processor.Accuracy);
ComboCounter?.Current.BindTo(processor.Combo);
if (HealthDisplay is StandardHealthDisplay shd)
processor.NewJudgement += shd.Flash;
if (HealthDisplay is IHealthDisplay shd)
{
processor.NewJudgement += judgement =>
{
if (judgement.IsHit && judgement.Type != HitResult.IgnoreHit)
shd.Flash(judgement);
};
}
}
protected virtual void BindHealthProcessor(HealthProcessor processor)