mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 05:32:54 +08:00
Merge pull request #26254 from frenzibyte/mania-combo-counter
Add argon/classic osu!mania combo counter
This commit is contained in:
commit
5710f0f302
@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
CreateTest();
|
||||
}
|
||||
|
||||
AddAssert("legacy HUD combo counter not added", () => !Player.ChildrenOfType<LegacyComboCounter>().Any());
|
||||
AddAssert("legacy HUD combo counter not added", () => !Player.ChildrenOfType<LegacyDefaultComboCounter>().Any());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
@ -32,12 +31,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
|
||||
switch (lookup)
|
||||
{
|
||||
case SkinComponentsContainerLookup containerLookup:
|
||||
if (containerLookup.Target != SkinComponentsContainerLookup.TargetArea.MainHUDComponents)
|
||||
return base.GetDrawableComponent(lookup);
|
||||
|
||||
// Modifications for global components.
|
||||
// Only handle per ruleset defaults here.
|
||||
if (containerLookup.Ruleset == null)
|
||||
return base.GetDrawableComponent(lookup) as Container;
|
||||
return base.GetDrawableComponent(lookup);
|
||||
|
||||
// Skin has configuration.
|
||||
if (base.GetDrawableComponent(lookup) is UserConfiguredLayoutContainer d)
|
||||
@ -48,6 +44,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
|
||||
return null;
|
||||
|
||||
// Our own ruleset components default.
|
||||
switch (containerLookup.Target)
|
||||
{
|
||||
case SkinComponentsContainerLookup.TargetArea.MainHUDComponents:
|
||||
// todo: remove CatchSkinComponents.CatchComboCounter and refactor LegacyCatchComboCounter to be added here instead.
|
||||
return new DefaultSkinComponentsContainer(container =>
|
||||
{
|
||||
@ -69,6 +68,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
|
||||
new LegacyKeyCounterDisplay(),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
case CatchSkinComponentLookup catchSkinComponent:
|
||||
switch (catchSkinComponent.Component)
|
||||
|
@ -0,0 +1,38 @@
|
||||
// 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.Testing;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Skinning.Argon;
|
||||
using osu.Game.Rulesets.Mania.Skinning.Legacy;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
{
|
||||
public partial class TestSceneComboCounter : ManiaSkinnableTestScene
|
||||
{
|
||||
[Cached]
|
||||
private ScoreProcessor scoreProcessor = new ScoreProcessor(new ManiaRuleset());
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetUpSteps()
|
||||
{
|
||||
AddStep("setup", () => SetContents(s =>
|
||||
{
|
||||
if (s is ArgonSkin)
|
||||
return new ArgonManiaComboCounter();
|
||||
|
||||
if (s is LegacySkin)
|
||||
return new LegacyManiaComboCounter();
|
||||
|
||||
return new LegacyManiaComboCounter();
|
||||
}));
|
||||
|
||||
AddRepeatStep("perform hit", () => scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement()) { Type = HitResult.Great }), 20);
|
||||
AddStep("perform miss", () => scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement()) { Type = HitResult.Miss }));
|
||||
}
|
||||
}
|
||||
}
|
@ -3,15 +3,22 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.UI;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
{
|
||||
public partial class TestScenePlayfield : ManiaSkinnableTestScene
|
||||
{
|
||||
[Cached]
|
||||
private ScoreProcessor scoreProcessor = new ScoreProcessor(new ManiaRuleset());
|
||||
|
||||
private List<StageDefinition> stageDefinitions = new List<StageDefinition>();
|
||||
|
||||
[Test]
|
||||
@ -29,6 +36,9 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
Child = new ManiaPlayfield(stageDefinitions)
|
||||
});
|
||||
});
|
||||
|
||||
AddRepeatStep("perform hit", () => scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement()) { Type = HitResult.Perfect }), 20);
|
||||
AddStep("perform miss", () => scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement()) { Type = HitResult.Miss }));
|
||||
}
|
||||
|
||||
[TestCase(2)]
|
||||
@ -54,6 +64,9 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
AddRepeatStep("perform hit", () => scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement()) { Type = HitResult.Perfect }), 20);
|
||||
AddStep("perform miss", () => scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement()) { Type = HitResult.Miss }));
|
||||
}
|
||||
|
||||
protected override IBeatmap CreateBeatmapForSkinProvider()
|
||||
|
@ -0,0 +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 NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Mods;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
{
|
||||
public partial class TestSceneManiaPlayerLegacySkin : LegacySkinPlayerTestScene
|
||||
{
|
||||
protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset();
|
||||
|
||||
// play with a converted beatmap to allow dual stages mod to work.
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(new RulesetInfo());
|
||||
|
||||
protected override bool HasCustomSteps => true;
|
||||
|
||||
[Test]
|
||||
public void TestSingleStage()
|
||||
{
|
||||
AddStep("Load single stage", LoadPlayer);
|
||||
AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDualStage()
|
||||
{
|
||||
AddStep("Load dual stage", () => LoadPlayer(new Mod[] { new ManiaModDualStages() }));
|
||||
AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
{
|
||||
public partial class ArgonManiaComboCounter : ArgonComboCounter
|
||||
{
|
||||
protected override bool DisplayXSymbol => false;
|
||||
|
||||
[Resolved]
|
||||
private IScrollingInfo scrollingInfo { get; set; } = null!;
|
||||
|
||||
private IBindable<ScrollingDirection> direction = null!;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
// the logic of flipping the position of the combo counter w.r.t. the direction does not work with "Closest" anchor,
|
||||
// because it always forces the anchor to be top or bottom based on scrolling direction.
|
||||
UsesFixedAnchor = true;
|
||||
|
||||
direction = scrollingInfo.Direction.GetBoundCopy();
|
||||
direction.BindValueChanged(_ => updateAnchor());
|
||||
|
||||
// two schedules are required so that updateAnchor is executed in the next frame,
|
||||
// which is when the combo counter receives its Y position by the default layout in ArgonManiaSkinTransformer.
|
||||
Schedule(() => Schedule(updateAnchor));
|
||||
}
|
||||
|
||||
private void updateAnchor()
|
||||
{
|
||||
// if the anchor isn't a vertical center, set top or bottom anchor based on scroll direction
|
||||
if (!Anchor.HasFlag(Anchor.y1))
|
||||
{
|
||||
Anchor &= ~(Anchor.y0 | Anchor.y2);
|
||||
Anchor |= direction.Value == ScrollingDirection.Up ? Anchor.y2 : Anchor.y0;
|
||||
}
|
||||
|
||||
// change the sign of the Y coordinate in line with the scrolling direction.
|
||||
// i.e. if the user changes direction from down to up, the anchor is changed from top to bottom, and the Y is flipped from positive to negative here.
|
||||
Y = Math.Abs(Y) * (direction.Value == ScrollingDirection.Up ? -1 : 1);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,8 +2,10 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -26,6 +28,37 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
{
|
||||
switch (lookup)
|
||||
{
|
||||
case SkinComponentsContainerLookup containerLookup:
|
||||
// Only handle per ruleset defaults here.
|
||||
if (containerLookup.Ruleset == null)
|
||||
return base.GetDrawableComponent(lookup);
|
||||
|
||||
// Skin has configuration.
|
||||
if (base.GetDrawableComponent(lookup) is UserConfiguredLayoutContainer d)
|
||||
return d;
|
||||
|
||||
switch (containerLookup.Target)
|
||||
{
|
||||
case SkinComponentsContainerLookup.TargetArea.MainHUDComponents:
|
||||
return new DefaultSkinComponentsContainer(container =>
|
||||
{
|
||||
var combo = container.ChildrenOfType<ArgonManiaComboCounter>().FirstOrDefault();
|
||||
|
||||
if (combo != null)
|
||||
{
|
||||
combo.ShowLabel.Value = false;
|
||||
combo.Anchor = Anchor.TopCentre;
|
||||
combo.Origin = Anchor.Centre;
|
||||
combo.Y = 200;
|
||||
}
|
||||
})
|
||||
{
|
||||
new ArgonManiaComboCounter(),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
case GameplaySkinComponentLookup<HitResult> resultComponent:
|
||||
// This should eventually be moved to a skin setting, when supported.
|
||||
if (Skin is ArgonProSkin && resultComponent.Component >= HitResult.Great)
|
||||
|
@ -0,0 +1,91 @@
|
||||
// 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;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Skinning.Legacy
|
||||
{
|
||||
public partial class LegacyManiaComboCounter : LegacyComboCounter
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ISkinSource skin)
|
||||
{
|
||||
DisplayedCountText.Anchor = Anchor.Centre;
|
||||
DisplayedCountText.Origin = Anchor.Centre;
|
||||
|
||||
PopOutCountText.Anchor = Anchor.Centre;
|
||||
PopOutCountText.Origin = Anchor.Centre;
|
||||
PopOutCountText.Colour = skin.GetManiaSkinConfig<Color4>(LegacyManiaSkinConfigurationLookups.ComboBreakColour)?.Value ?? Color4.Red;
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private IScrollingInfo scrollingInfo { get; set; } = null!;
|
||||
|
||||
private IBindable<ScrollingDirection> direction = null!;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
direction = scrollingInfo.Direction.GetBoundCopy();
|
||||
direction.BindValueChanged(_ => updateAnchor());
|
||||
|
||||
// two schedules are required so that updateAnchor is executed in the next frame,
|
||||
// which is when the combo counter receives its Y position by the default layout in LegacyManiaSkinTransformer.
|
||||
Schedule(() => Schedule(updateAnchor));
|
||||
}
|
||||
|
||||
private void updateAnchor()
|
||||
{
|
||||
// if the anchor isn't a vertical center, set top or bottom anchor based on scroll direction
|
||||
if (!Anchor.HasFlag(Anchor.y1))
|
||||
{
|
||||
Anchor &= ~(Anchor.y0 | Anchor.y2);
|
||||
Anchor |= direction.Value == ScrollingDirection.Up ? Anchor.y2 : Anchor.y0;
|
||||
}
|
||||
|
||||
// since we flip the vertical anchor when changing scroll direction,
|
||||
// we can use the sign of the Y value as an indicator to make the combo counter displayed correctly.
|
||||
if ((Y < 0 && direction.Value == ScrollingDirection.Down) || (Y > 0 && direction.Value == ScrollingDirection.Up))
|
||||
Y = -Y;
|
||||
}
|
||||
|
||||
protected override void OnCountIncrement()
|
||||
{
|
||||
base.OnCountIncrement();
|
||||
|
||||
PopOutCountText.Hide();
|
||||
DisplayedCountText.ScaleTo(new Vector2(1f, 1.4f))
|
||||
.ScaleTo(new Vector2(1f), 300, Easing.Out)
|
||||
.FadeIn(120);
|
||||
}
|
||||
|
||||
protected override void OnCountChange()
|
||||
{
|
||||
base.OnCountChange();
|
||||
|
||||
PopOutCountText.Hide();
|
||||
DisplayedCountText.ScaleTo(1f);
|
||||
}
|
||||
|
||||
protected override void OnCountRolling()
|
||||
{
|
||||
if (DisplayedCount > 0)
|
||||
{
|
||||
PopOutCountText.Text = FormatCount(DisplayedCount);
|
||||
PopOutCountText.FadeTo(0.8f).FadeOut(200)
|
||||
.ScaleTo(1f).ScaleTo(4f, 200);
|
||||
|
||||
DisplayedCountText.FadeTo(0.5f, 300);
|
||||
}
|
||||
|
||||
base.OnCountRolling();
|
||||
}
|
||||
}
|
||||
}
|
@ -5,9 +5,11 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
@ -78,6 +80,40 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
|
||||
{
|
||||
switch (lookup)
|
||||
{
|
||||
case SkinComponentsContainerLookup containerLookup:
|
||||
// Modifications for global components.
|
||||
if (containerLookup.Ruleset == null)
|
||||
return base.GetDrawableComponent(lookup);
|
||||
|
||||
// Skin has configuration.
|
||||
if (base.GetDrawableComponent(lookup) is UserConfiguredLayoutContainer d)
|
||||
return d;
|
||||
|
||||
// we don't have enough assets to display these components (this is especially the case on a "beatmap" skin).
|
||||
if (!IsProvidingLegacyResources)
|
||||
return null;
|
||||
|
||||
switch (containerLookup.Target)
|
||||
{
|
||||
case SkinComponentsContainerLookup.TargetArea.MainHUDComponents:
|
||||
return new DefaultSkinComponentsContainer(container =>
|
||||
{
|
||||
var combo = container.ChildrenOfType<LegacyManiaComboCounter>().FirstOrDefault();
|
||||
|
||||
if (combo != null)
|
||||
{
|
||||
combo.Anchor = Anchor.TopCentre;
|
||||
combo.Origin = Anchor.Centre;
|
||||
combo.Y = this.GetManiaSkinConfig<float>(LegacyManiaSkinConfigurationLookups.ComboPosition)?.Value ?? 0;
|
||||
}
|
||||
})
|
||||
{
|
||||
new LegacyManiaComboCounter(),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
case GameplaySkinComponentLookup<HitResult> resultComponent:
|
||||
return getResult(resultComponent.Component);
|
||||
|
||||
|
@ -74,11 +74,20 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
// 340px is the default height inherit from stable
|
||||
keyCounter.Y = container.ToLocalSpace(new Vector2(0, container.ScreenSpaceDrawQuad.Centre.Y - 340f)).Y;
|
||||
}
|
||||
|
||||
var combo = container.OfType<LegacyDefaultComboCounter>().FirstOrDefault();
|
||||
|
||||
if (combo != null)
|
||||
{
|
||||
combo.Anchor = Anchor.BottomLeft;
|
||||
combo.Origin = Anchor.BottomLeft;
|
||||
combo.Scale = new Vector2(1.28f);
|
||||
}
|
||||
})
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new LegacyComboCounter(),
|
||||
new LegacyDefaultComboCounter(),
|
||||
new LegacyKeyCounterDisplay(),
|
||||
}
|
||||
};
|
||||
@ -90,7 +99,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
switch (osuComponent.Component)
|
||||
{
|
||||
case OsuSkinComponents.FollowPoint:
|
||||
return this.GetAnimation("followpoint", true, true, true, startAtCurrentTime: false, maxSize: new Vector2(OsuHitObject.OBJECT_RADIUS * 2, OsuHitObject.OBJECT_RADIUS));
|
||||
return this.GetAnimation("followpoint", true, true, true, startAtCurrentTime: false,
|
||||
maxSize: new Vector2(OsuHitObject.OBJECT_RADIUS * 2, OsuHitObject.OBJECT_RADIUS));
|
||||
|
||||
case OsuSkinComponents.SliderScorePoint:
|
||||
return this.GetAnimation("sliderscorepoint", false, false, maxSize: OsuHitObject.OBJECT_DIMENSIONS);
|
||||
|
@ -443,7 +443,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddAssert("no combo in global target", () => !globalHUDTarget.Components.OfType<LegacyComboCounter>().Any());
|
||||
AddAssert("combo placed in ruleset target", () => rulesetHUDTarget.Components.OfType<LegacyComboCounter>().Count() == 1);
|
||||
|
||||
AddStep("add combo to global target", () => globalHUDTarget.Add(new LegacyComboCounter
|
||||
AddStep("add combo to global target", () => globalHUDTarget.Add(new LegacyDefaultComboCounter
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
protected override Drawable CreateArgonImplementation() => new ArgonComboCounter();
|
||||
protected override Drawable CreateDefaultImplementation() => new DefaultComboCounter();
|
||||
protected override Drawable CreateLegacyImplementation() => new LegacyComboCounter();
|
||||
protected override Drawable CreateLegacyImplementation() => new LegacyDefaultComboCounter();
|
||||
|
||||
[Test]
|
||||
public void TestComboCounterIncrementing()
|
||||
|
@ -19,10 +19,12 @@ namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public partial class ArgonComboCounter : ComboCounter
|
||||
{
|
||||
private ArgonCounterTextComponent text = null!;
|
||||
protected ArgonCounterTextComponent Text = null!;
|
||||
|
||||
protected override double RollingDuration => 250;
|
||||
|
||||
protected virtual bool DisplayXSymbol => true;
|
||||
|
||||
[SettingSource("Wireframe opacity", "Controls the opacity of the wireframes behind the digits.")]
|
||||
public BindableFloat WireframeOpacity { get; } = new BindableFloat(0.25f)
|
||||
{
|
||||
@ -43,16 +45,16 @@ namespace osu.Game.Screens.Play.HUD
|
||||
bool wasIncrease = combo.NewValue > combo.OldValue;
|
||||
bool wasMiss = combo.OldValue > 1 && combo.NewValue == 0;
|
||||
|
||||
float newScale = Math.Clamp(text.NumberContainer.Scale.X * (wasIncrease ? 1.1f : 0.8f), 0.6f, 1.4f);
|
||||
float newScale = Math.Clamp(Text.NumberContainer.Scale.X * (wasIncrease ? 1.1f : 0.8f), 0.6f, 1.4f);
|
||||
|
||||
float duration = wasMiss ? 2000 : 500;
|
||||
|
||||
text.NumberContainer
|
||||
Text.NumberContainer
|
||||
.ScaleTo(new Vector2(newScale))
|
||||
.ScaleTo(Vector2.One, duration, Easing.OutQuint);
|
||||
|
||||
if (wasMiss)
|
||||
text.FlashColour(Color4.Red, duration, Easing.OutQuint);
|
||||
Text.FlashColour(Color4.Red, duration, Easing.OutQuint);
|
||||
});
|
||||
}
|
||||
|
||||
@ -70,23 +72,23 @@ namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
int digitsRequiredForDisplayCount = getDigitsRequiredForDisplayCount();
|
||||
|
||||
if (digitsRequiredForDisplayCount != text.WireframeTemplate.Length)
|
||||
text.WireframeTemplate = new string('#', digitsRequiredForDisplayCount);
|
||||
if (digitsRequiredForDisplayCount != Text.WireframeTemplate.Length)
|
||||
Text.WireframeTemplate = new string('#', digitsRequiredForDisplayCount);
|
||||
}
|
||||
|
||||
private int getDigitsRequiredForDisplayCount()
|
||||
{
|
||||
// one for the single presumed starting digit, one for the "x" at the end.
|
||||
int digitsRequired = 2;
|
||||
// one for the single presumed starting digit, one for the "x" at the end (unless disabled).
|
||||
int digitsRequired = DisplayXSymbol ? 2 : 1;
|
||||
long c = DisplayedCount;
|
||||
while ((c /= 10) > 0)
|
||||
digitsRequired++;
|
||||
return digitsRequired;
|
||||
}
|
||||
|
||||
protected override LocalisableString FormatCount(int count) => $@"{count}x";
|
||||
protected override LocalisableString FormatCount(int count) => DisplayXSymbol ? $@"{count}x" : count.ToString();
|
||||
|
||||
protected override IHasText CreateText() => text = new ArgonCounterTextComponent(Anchor.TopLeft, MatchesStrings.MatchScoreStatsCombo.ToUpper())
|
||||
protected override IHasText CreateText() => Text = new ArgonCounterTextComponent(Anchor.TopLeft, MatchesStrings.MatchScoreStatsCombo.ToUpper())
|
||||
{
|
||||
WireframeOpacity = { BindTarget = WireframeOpacity },
|
||||
ShowLabel = { BindTarget = ShowLabel },
|
||||
|
@ -32,6 +32,7 @@ using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Scoring.Legacy;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
@ -236,6 +237,9 @@ namespace osu.Game.Screens.Play
|
||||
DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods);
|
||||
dependencies.CacheAs(DrawableRuleset);
|
||||
|
||||
if (DrawableRuleset is IDrawableScrollingRuleset scrollingRuleset)
|
||||
dependencies.CacheAs(scrollingRuleset.ScrollingInfo);
|
||||
|
||||
ScoreProcessor = ruleset.CreateScoreProcessor();
|
||||
ScoreProcessor.Mods.Value = gameplayMods;
|
||||
ScoreProcessor.ApplyBeatmap(playableBeatmap);
|
||||
|
@ -5,25 +5,17 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
/// <summary>
|
||||
/// Uses the 'x' symbol and has a pop-out effect while rolling over.
|
||||
/// </summary>
|
||||
public partial class LegacyComboCounter : CompositeDrawable, ISerialisableDrawable
|
||||
public abstract partial class LegacyComboCounter : CompositeDrawable, ISerialisableDrawable
|
||||
{
|
||||
public Bindable<int> Current { get; } = new BindableInt { MinValue = 0 };
|
||||
|
||||
private uint scheduledPopOutCurrentId;
|
||||
|
||||
private const double big_pop_out_duration = 300;
|
||||
|
||||
private const double small_pop_out_duration = 100;
|
||||
|
||||
private const double fade_out_duration = 100;
|
||||
|
||||
/// <summary>
|
||||
@ -31,9 +23,8 @@ namespace osu.Game.Skinning
|
||||
/// </summary>
|
||||
private const double rolling_duration = 20;
|
||||
|
||||
private readonly Drawable popOutCount;
|
||||
|
||||
private readonly Drawable displayedCountSpriteText;
|
||||
protected readonly LegacySpriteText PopOutCountText;
|
||||
protected readonly LegacySpriteText DisplayedCountText;
|
||||
|
||||
private int previousValue;
|
||||
|
||||
@ -45,17 +36,10 @@ namespace osu.Game.Skinning
|
||||
|
||||
public bool UsesFixedAnchor { get; set; }
|
||||
|
||||
public LegacyComboCounter()
|
||||
protected LegacyComboCounter()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Anchor = Anchor.BottomLeft;
|
||||
Origin = Anchor.BottomLeft;
|
||||
|
||||
Margin = new MarginPadding(10);
|
||||
|
||||
Scale = new Vector2(1.28f);
|
||||
|
||||
InternalChildren = new[]
|
||||
{
|
||||
counterContainer = new Container
|
||||
@ -63,18 +47,16 @@ namespace osu.Game.Skinning
|
||||
AlwaysPresent = true,
|
||||
Children = new[]
|
||||
{
|
||||
popOutCount = new LegacySpriteText(LegacyFont.Combo)
|
||||
PopOutCountText = new LegacySpriteText(LegacyFont.Combo)
|
||||
{
|
||||
Alpha = 0,
|
||||
Blending = BlendingParameters.Additive,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
BypassAutoSizeAxes = Axes.Both,
|
||||
},
|
||||
displayedCountSpriteText = new LegacySpriteText(LegacyFont.Combo)
|
||||
DisplayedCountText = new LegacySpriteText(LegacyFont.Combo)
|
||||
{
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
BypassAutoSizeAxes = Axes.Both,
|
||||
},
|
||||
}
|
||||
@ -114,26 +96,12 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
((IHasText)displayedCountSpriteText).Text = formatCount(Current.Value);
|
||||
((IHasText)popOutCount).Text = formatCount(Current.Value);
|
||||
DisplayedCountText.Text = FormatCount(Current.Value);
|
||||
PopOutCountText.Text = FormatCount(Current.Value);
|
||||
|
||||
Current.BindValueChanged(combo => updateCount(combo.NewValue == 0), true);
|
||||
|
||||
updateLayout();
|
||||
}
|
||||
|
||||
private void updateLayout()
|
||||
{
|
||||
const float font_height_ratio = 0.625f;
|
||||
const float vertical_offset = 9;
|
||||
|
||||
displayedCountSpriteText.OriginPosition = new Vector2(0, font_height_ratio * displayedCountSpriteText.Height + vertical_offset);
|
||||
displayedCountSpriteText.Position = new Vector2(0, -(1 - font_height_ratio) * displayedCountSpriteText.Height + vertical_offset);
|
||||
|
||||
popOutCount.OriginPosition = new Vector2(3, font_height_ratio * popOutCount.Height + vertical_offset); // In stable, the bigger pop out scales a bit to the left
|
||||
popOutCount.Position = new Vector2(0, -(1 - font_height_ratio) * popOutCount.Height + vertical_offset);
|
||||
|
||||
counterContainer.Size = displayedCountSpriteText.Size;
|
||||
counterContainer.Size = DisplayedCountText.Size;
|
||||
}
|
||||
|
||||
private void updateCount(bool rolling)
|
||||
@ -147,127 +115,84 @@ namespace osu.Game.Skinning
|
||||
if (!rolling)
|
||||
{
|
||||
FinishTransforms(false, nameof(DisplayedCount));
|
||||
|
||||
isRolling = false;
|
||||
DisplayedCount = prev;
|
||||
|
||||
if (prev + 1 == Current.Value)
|
||||
onCountIncrement(prev, Current.Value);
|
||||
OnCountIncrement();
|
||||
else
|
||||
onCountChange(Current.Value);
|
||||
OnCountChange();
|
||||
}
|
||||
else
|
||||
{
|
||||
onCountRolling(displayedCount, Current.Value);
|
||||
OnCountRolling();
|
||||
isRolling = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void transformPopOut(int newValue)
|
||||
/// <summary>
|
||||
/// Raised when the counter should display the new value with transitions.
|
||||
/// </summary>
|
||||
protected virtual void OnCountIncrement()
|
||||
{
|
||||
((IHasText)popOutCount).Text = formatCount(newValue);
|
||||
|
||||
popOutCount.ScaleTo(1.56f)
|
||||
.ScaleTo(1, big_pop_out_duration);
|
||||
|
||||
popOutCount.FadeTo(0.6f)
|
||||
.FadeOut(big_pop_out_duration);
|
||||
}
|
||||
|
||||
private void transformNoPopOut(int newValue)
|
||||
{
|
||||
((IHasText)displayedCountSpriteText).Text = formatCount(newValue);
|
||||
|
||||
counterContainer.Size = displayedCountSpriteText.Size;
|
||||
|
||||
displayedCountSpriteText.ScaleTo(1);
|
||||
}
|
||||
|
||||
private void transformPopOutSmall(int newValue)
|
||||
{
|
||||
((IHasText)displayedCountSpriteText).Text = formatCount(newValue);
|
||||
|
||||
counterContainer.Size = displayedCountSpriteText.Size;
|
||||
|
||||
displayedCountSpriteText.ScaleTo(1).Then()
|
||||
.ScaleTo(1.1f, small_pop_out_duration / 2, Easing.In).Then()
|
||||
.ScaleTo(1, small_pop_out_duration / 2, Easing.Out);
|
||||
}
|
||||
|
||||
private void scheduledPopOutSmall(uint id)
|
||||
{
|
||||
// Too late; scheduled task invalidated
|
||||
if (id != scheduledPopOutCurrentId)
|
||||
return;
|
||||
if (DisplayedCount < Current.Value - 1)
|
||||
DisplayedCount++;
|
||||
|
||||
DisplayedCount++;
|
||||
}
|
||||
|
||||
private void onCountIncrement(int currentValue, int newValue)
|
||||
/// <summary>
|
||||
/// Raised when the counter should roll to the new combo value (usually roll back to zero).
|
||||
/// </summary>
|
||||
protected virtual void OnCountRolling()
|
||||
{
|
||||
scheduledPopOutCurrentId++;
|
||||
|
||||
if (DisplayedCount < currentValue)
|
||||
DisplayedCount++;
|
||||
|
||||
displayedCountSpriteText.Show();
|
||||
|
||||
transformPopOut(newValue);
|
||||
|
||||
uint newTaskId = scheduledPopOutCurrentId;
|
||||
|
||||
Scheduler.AddDelayed(delegate
|
||||
{
|
||||
scheduledPopOutSmall(newTaskId);
|
||||
}, big_pop_out_duration - 140);
|
||||
}
|
||||
|
||||
private void onCountRolling(int currentValue, int newValue)
|
||||
{
|
||||
scheduledPopOutCurrentId++;
|
||||
|
||||
// Hides displayed count if was increasing from 0 to 1 but didn't finish
|
||||
if (currentValue == 0 && newValue == 0)
|
||||
displayedCountSpriteText.FadeOut(fade_out_duration);
|
||||
if (DisplayedCount == 0 && Current.Value == 0)
|
||||
DisplayedCountText.FadeOut(fade_out_duration);
|
||||
|
||||
transformRoll(currentValue, newValue);
|
||||
transformRoll(DisplayedCount, Current.Value);
|
||||
}
|
||||
|
||||
private void onCountChange(int newValue)
|
||||
/// <summary>
|
||||
/// Raised when the counter should display the new combo value without any transitions.
|
||||
/// </summary>
|
||||
protected virtual void OnCountChange()
|
||||
{
|
||||
scheduledPopOutCurrentId++;
|
||||
if (Current.Value == 0)
|
||||
DisplayedCountText.FadeOut();
|
||||
|
||||
if (newValue == 0)
|
||||
displayedCountSpriteText.FadeOut();
|
||||
|
||||
DisplayedCount = newValue;
|
||||
DisplayedCount = Current.Value;
|
||||
}
|
||||
|
||||
private void onDisplayedCountRolling(int newValue)
|
||||
{
|
||||
if (newValue == 0)
|
||||
displayedCountSpriteText.FadeOut(fade_out_duration);
|
||||
else
|
||||
displayedCountSpriteText.Show();
|
||||
DisplayedCountText.FadeOut(fade_out_duration);
|
||||
|
||||
transformNoPopOut(newValue);
|
||||
DisplayedCountText.Text = FormatCount(newValue);
|
||||
counterContainer.Size = DisplayedCountText.Size;
|
||||
}
|
||||
|
||||
private void onDisplayedCountChange(int newValue)
|
||||
{
|
||||
displayedCountSpriteText.FadeTo(newValue == 0 ? 0 : 1);
|
||||
transformNoPopOut(newValue);
|
||||
DisplayedCountText.FadeTo(newValue == 0 ? 0 : 1);
|
||||
DisplayedCountText.Text = FormatCount(newValue);
|
||||
|
||||
counterContainer.Size = DisplayedCountText.Size;
|
||||
}
|
||||
|
||||
private void onDisplayedCountIncrement(int newValue)
|
||||
{
|
||||
displayedCountSpriteText.Show();
|
||||
transformPopOutSmall(newValue);
|
||||
DisplayedCountText.Text = FormatCount(newValue);
|
||||
|
||||
counterContainer.Size = DisplayedCountText.Size;
|
||||
}
|
||||
|
||||
private void transformRoll(int currentValue, int newValue) =>
|
||||
this.TransformTo(nameof(DisplayedCount), newValue, getProportionalDuration(currentValue, newValue));
|
||||
|
||||
private string formatCount(int count) => $@"{count}x";
|
||||
protected virtual string FormatCount(int count) => $@"{count}";
|
||||
|
||||
private double getProportionalDuration(int currentValue, int newValue)
|
||||
{
|
||||
|
85
osu.Game/Skinning/LegacyDefaultComboCounter.cs
Normal file
85
osu.Game/Skinning/LegacyDefaultComboCounter.cs
Normal file
@ -0,0 +1,85 @@
|
||||
// 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.Threading;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
/// <summary>
|
||||
/// Uses the 'x' symbol and has a pop-out effect while rolling over.
|
||||
/// </summary>
|
||||
public partial class LegacyDefaultComboCounter : LegacyComboCounter
|
||||
{
|
||||
private const double big_pop_out_duration = 300;
|
||||
private const double small_pop_out_duration = 100;
|
||||
|
||||
private ScheduledDelegate? scheduledPopOut;
|
||||
|
||||
public LegacyDefaultComboCounter()
|
||||
{
|
||||
Margin = new MarginPadding(10);
|
||||
|
||||
PopOutCountText.Anchor = Anchor.BottomLeft;
|
||||
DisplayedCountText.Anchor = Anchor.BottomLeft;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
const float font_height_ratio = 0.625f;
|
||||
const float vertical_offset = 9;
|
||||
|
||||
DisplayedCountText.OriginPosition = new Vector2(0, font_height_ratio * DisplayedCountText.Height + vertical_offset);
|
||||
DisplayedCountText.Position = new Vector2(0, -(1 - font_height_ratio) * DisplayedCountText.Height + vertical_offset);
|
||||
|
||||
PopOutCountText.OriginPosition = new Vector2(3, font_height_ratio * PopOutCountText.Height + vertical_offset); // In stable, the bigger pop out scales a bit to the left
|
||||
PopOutCountText.Position = new Vector2(0, -(1 - font_height_ratio) * PopOutCountText.Height + vertical_offset);
|
||||
}
|
||||
|
||||
protected override void OnCountIncrement()
|
||||
{
|
||||
scheduledPopOut?.Cancel();
|
||||
scheduledPopOut = null;
|
||||
|
||||
DisplayedCountText.Show();
|
||||
|
||||
PopOutCountText.Text = FormatCount(Current.Value);
|
||||
|
||||
PopOutCountText.ScaleTo(1.56f)
|
||||
.ScaleTo(1, big_pop_out_duration);
|
||||
|
||||
PopOutCountText.FadeTo(0.6f)
|
||||
.FadeOut(big_pop_out_duration);
|
||||
|
||||
this.Delay(big_pop_out_duration - 140).Schedule(() =>
|
||||
{
|
||||
base.OnCountIncrement();
|
||||
|
||||
DisplayedCountText.ScaleTo(1).Then()
|
||||
.ScaleTo(1.1f, small_pop_out_duration / 2, Easing.In).Then()
|
||||
.ScaleTo(1, small_pop_out_duration / 2, Easing.Out);
|
||||
}, out scheduledPopOut);
|
||||
}
|
||||
|
||||
protected override void OnCountRolling()
|
||||
{
|
||||
scheduledPopOut?.Cancel();
|
||||
scheduledPopOut = null;
|
||||
|
||||
base.OnCountRolling();
|
||||
}
|
||||
|
||||
protected override void OnCountChange()
|
||||
{
|
||||
scheduledPopOut?.Cancel();
|
||||
scheduledPopOut = null;
|
||||
|
||||
base.OnCountChange();
|
||||
}
|
||||
|
||||
protected override string FormatCount(int count) => $@"{count}x";
|
||||
}
|
||||
}
|
@ -39,6 +39,7 @@ namespace osu.Game.Skinning
|
||||
|
||||
public float HitPosition = DEFAULT_HIT_POSITION;
|
||||
public float LightPosition = (480 - 413) * POSITION_SCALE_FACTOR;
|
||||
public float ComboPosition = 111 * POSITION_SCALE_FACTOR;
|
||||
public float ScorePosition = 300 * POSITION_SCALE_FACTOR;
|
||||
public bool ShowJudgementLine = true;
|
||||
public bool KeysUnderNotes;
|
||||
|
@ -42,6 +42,7 @@ namespace osu.Game.Skinning
|
||||
LeftLineWidth,
|
||||
RightLineWidth,
|
||||
HitPosition,
|
||||
ComboPosition,
|
||||
ScorePosition,
|
||||
LightPosition,
|
||||
StagePaddingTop,
|
||||
@ -63,6 +64,7 @@ namespace osu.Game.Skinning
|
||||
JudgementLineColour,
|
||||
ColumnBackgroundColour,
|
||||
ColumnLightColour,
|
||||
ComboBreakColour,
|
||||
MinimumColumnWidth,
|
||||
LeftStageImage,
|
||||
RightStageImage,
|
||||
|
@ -94,6 +94,10 @@ namespace osu.Game.Skinning
|
||||
currentConfig.LightPosition = (480 - float.Parse(pair.Value, CultureInfo.InvariantCulture)) * LegacyManiaSkinConfiguration.POSITION_SCALE_FACTOR;
|
||||
break;
|
||||
|
||||
case "ComboPosition":
|
||||
currentConfig.ComboPosition = (float.Parse(pair.Value, CultureInfo.InvariantCulture)) * LegacyManiaSkinConfiguration.POSITION_SCALE_FACTOR;
|
||||
break;
|
||||
|
||||
case "ScorePosition":
|
||||
currentConfig.ScorePosition = (float.Parse(pair.Value, CultureInfo.InvariantCulture)) * LegacyManiaSkinConfiguration.POSITION_SCALE_FACTOR;
|
||||
break;
|
||||
|
@ -13,7 +13,6 @@ using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Game.Audio;
|
||||
@ -24,6 +23,7 @@ using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
@ -155,6 +155,9 @@ namespace osu.Game.Skinning
|
||||
case LegacyManiaSkinConfigurationLookups.HitPosition:
|
||||
return SkinUtils.As<TValue>(new Bindable<float>(existing.HitPosition));
|
||||
|
||||
case LegacyManiaSkinConfigurationLookups.ComboPosition:
|
||||
return SkinUtils.As<TValue>(new Bindable<float>(existing.ComboPosition));
|
||||
|
||||
case LegacyManiaSkinConfigurationLookups.ScorePosition:
|
||||
return SkinUtils.As<TValue>(new Bindable<float>(existing.ScorePosition));
|
||||
|
||||
@ -192,6 +195,9 @@ namespace osu.Game.Skinning
|
||||
Debug.Assert(maniaLookup.ColumnIndex != null);
|
||||
return SkinUtils.As<TValue>(getCustomColour(existing, $"ColourLight{maniaLookup.ColumnIndex + 1}"));
|
||||
|
||||
case LegacyManiaSkinConfigurationLookups.ComboBreakColour:
|
||||
return SkinUtils.As<TValue>(getCustomColour(existing, "ColourBreak"));
|
||||
|
||||
case LegacyManiaSkinConfigurationLookups.MinimumColumnWidth:
|
||||
return SkinUtils.As<TValue>(new Bindable<float>(existing.MinimumColumnWidth));
|
||||
|
||||
@ -361,10 +367,19 @@ namespace osu.Game.Skinning
|
||||
case SkinComponentsContainerLookup.TargetArea.MainHUDComponents:
|
||||
if (containerLookup.Ruleset != null)
|
||||
{
|
||||
return new Container
|
||||
return new DefaultSkinComponentsContainer(container =>
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = new LegacyComboCounter(),
|
||||
var combo = container.OfType<LegacyDefaultComboCounter>().FirstOrDefault();
|
||||
|
||||
if (combo != null)
|
||||
{
|
||||
combo.Anchor = Anchor.BottomLeft;
|
||||
combo.Origin = Anchor.BottomLeft;
|
||||
combo.Scale = new Vector2(1.28f);
|
||||
}
|
||||
})
|
||||
{
|
||||
new LegacyDefaultComboCounter()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -213,6 +213,7 @@ namespace osu.Game.Skinning
|
||||
// handle namespace changes...
|
||||
jsonContent = jsonContent.Replace(@"osu.Game.Screens.Play.SongProgress", @"osu.Game.Screens.Play.HUD.DefaultSongProgress");
|
||||
jsonContent = jsonContent.Replace(@"osu.Game.Screens.Play.HUD.LegacyComboCounter", @"osu.Game.Skinning.LegacyComboCounter");
|
||||
jsonContent = jsonContent.Replace(@"osu.Game.Skinning.LegacyComboCounter", @"osu.Game.Skinning.LegacyDefaultComboCounter");
|
||||
jsonContent = jsonContent.Replace(@"osu.Game.Screens.Play.HUD.PerformancePointsCounter", @"osu.Game.Skinning.Triangles.TrianglesPerformancePointsCounter");
|
||||
|
||||
try
|
||||
@ -250,13 +251,15 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
// Combo counters were moved out of the global HUD components into per-ruleset.
|
||||
// This is to allow some rulesets to customise further (ie. mania and catch moving the combo to within their play area).
|
||||
if (target != SkinComponentsContainerLookup.TargetArea.MainHUDComponents ||
|
||||
!layout.TryGetDrawableInfo(null, out var globalHUDComponents) ||
|
||||
resources == null)
|
||||
break;
|
||||
|
||||
var comboCounters = globalHUDComponents.Where(c =>
|
||||
c.Type.Name == nameof(LegacyComboCounter) ||
|
||||
c.Type.Name == nameof(LegacyDefaultComboCounter) ||
|
||||
c.Type.Name == nameof(DefaultComboCounter) ||
|
||||
c.Type.Name == nameof(ArgonComboCounter)).ToArray();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user