Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor classic osu!catch combo counter and place it in HUD overlay #26253

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5369d9a
Refactor legacy catch combo counter and place it in HUD overlay
frenzibyte Dec 30, 2023
e0b4b1f
Disable "closest" anchor in catch combo counter for convenience
frenzibyte Dec 30, 2023
e434d2b
Fix skin editor scaling not working
frenzibyte Dec 30, 2023
945c324
Merge branch 'master' into refactor-catch-combo-counter
peppy Aug 19, 2024
3b3b879
Adjust legacy catch combo counter to match stable's animations / scale
peppy Aug 19, 2024
6cc7b94
Re-remove `SupportsClosestAnchor`
peppy Aug 19, 2024
6bcf8b3
Fix test and more tidying up
peppy Aug 19, 2024
cf4a354
Use `LegacyComboCounter` base class rather than reimplementing everyt…
peppy Aug 19, 2024
f7fc75d
Fix readability of x positioning logic
peppy Aug 19, 2024
8fd296d
Fix test not really applying a combo colour
peppy Aug 19, 2024
d5ce317
Add migration support
peppy Aug 19, 2024
a982519
Make default placement of legacy catch combo counter a bit more sane
peppy Aug 19, 2024
1c7b8c8
Fix delay time not matching stable
frenzibyte Aug 19, 2024
c04743e
Add explanatory note to migration
frenzibyte Aug 19, 2024
c8f5f3a
Remove unnecessary property
frenzibyte Aug 19, 2024
f979def
Fix test passing despite no layout being loaded
frenzibyte Aug 19, 2024
1d0255f
It's the other direction
frenzibyte Aug 19, 2024
38be124
Add explanatory note
frenzibyte Aug 19, 2024
fdd23c5
Fix migration being applied to all targets
frenzibyte Aug 19, 2024
f944ac5
Specifiy sane anchor/origin during migration
frenzibyte Aug 19, 2024
2b86a73
Fix editor saving test scene not working with many rulesets
frenzibyte Aug 19, 2024
d05ca71
Add tests project reference to android
frenzibyte Aug 20, 2024
25dbebd
Merge branch 'master' into refactor-catch-combo-counter
peppy Sep 30, 2024
85f0134
Remove `LegacyComboCounter` again
frenzibyte Oct 30, 2024
594557e
Merge branch 'master' into refactor-catch-combo-counter
frenzibyte Oct 30, 2024
cfc8b78
Attempt to salvage a bug from "floating fruits" mod
frenzibyte Nov 3, 2024
8e0b784
Merge branch 'master' into refactor-catch-combo-counter
frenzibyte Nov 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<ProjectReference Include="..\osu.Game.Tests\osu.Game.Tests.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
</Project>
84 changes: 84 additions & 0 deletions osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinMigration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Database;
using osu.Game.Overlays;
using osu.Game.Overlays.SkinEditor;
using osu.Game.Rulesets.Catch.Skinning.Legacy;
using osu.Game.Screens.Edit;
using osu.Game.Skinning;
using osu.Game.Tests.Resources;
using osu.Game.Tests.Visual;

namespace osu.Game.Rulesets.Catch.Tests
{
[HeadlessTest]
public partial class TestSceneCatchSkinMigration : PlayerTestScene
{
private SkinEditor skinEditor = null!;

protected override bool Autoplay => true;

[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);

[Cached]
public readonly EditorClipboard Clipboard = new EditorClipboard();

[Resolved]
private SkinManager skins { get; set; } = null!;

private SkinnableContainer targetContainer => Player.ChildrenOfType<SkinnableContainer>().First();

private SkinnableContainer rulesetHUDTarget => Player.ChildrenOfType<SkinnableContainer>()
.Single(c => c.Lookup.Lookup == GlobalSkinnableContainers.MainHUDComponents && c.Lookup.Ruleset != null);

[SetUpSteps]
public override void SetUpSteps()
{
base.SetUpSteps();

AddStep("reset skin", () => skins.CurrentSkinInfo.SetDefault());
AddUntilStep("wait for hud load", () => targetContainer.ComponentsLoaded);

AddStep("reload skin editor", () =>
{
if (skinEditor.IsNotNull())
skinEditor.Expire();
Player.ScaleTo(0.4f);
LoadComponentAsync(skinEditor = new SkinEditor(Player), Add);
});
AddUntilStep("wait for loaded", () => skinEditor.IsLoaded);
}

[Test]
public void TestMigrationLegacyCatch()
{
AddStep("import old classic skin", () => skins.CurrentSkinInfo.Value = importSkinFromArchives(@"classic-layout-version-0.osk").SkinInfo);
AddAssert("layout loaded", () => skins.CurrentSkin.Value.LayoutInfos, () => NUnit.Framework.Contains.Key(GlobalSkinnableContainers.MainHUDComponents));
AddUntilStep("wait for load", () => rulesetHUDTarget.ComponentsLoaded);

AddAssert("catch specific combo counter in ruleset target", () => rulesetHUDTarget.Components.OfType<LegacyCatchComboCounter>(), () => Has.One.Items);
AddAssert("correct anchor/origin", () =>
{
var catchComboCounter = rulesetHUDTarget.Components.OfType<LegacyCatchComboCounter>().Single();
return catchComboCounter.Anchor == Anchor.CentreLeft && catchComboCounter.Origin == Anchor.Centre;
});
}

private Skin importSkinFromArchives(string filename)
{
var imported = skins.Import(new ImportTask(TestResources.OpenResource($@"Archives/{filename}"), filename)).GetResultSafely();
return imported.PerformRead(skinInfo => skins.GetSkin(skinInfo));
}

protected override Ruleset CreatePlayerRuleset() => new CatchRuleset();
}
}
90 changes: 52 additions & 38 deletions osu.Game.Rulesets.Catch.Tests/TestSceneComboCounter.cs
Original file line number Diff line number Diff line change
@@ -1,88 +1,102 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawables;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Catch.Skinning.Legacy;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play;
using osu.Game.Tests.Visual;
using osuTK;
using osu.Game.Skinning;
using osu.Game.Tests.Gameplay;
using osuTK.Graphics;

namespace osu.Game.Rulesets.Catch.Tests
{
public partial class TestSceneComboCounter : CatchSkinnableTestScene
{
private ScoreProcessor scoreProcessor = null!;
private readonly GameplayState gameplayState = TestGameplayState.Create(new CatchRuleset());

private Color4 judgedObjectColour = Color4.White;
[Cached(typeof(ScoreProcessor))]
private ScoreProcessor scoreProcessor;

private readonly Bindable<bool> showHud = new Bindable<bool>(true);
private Color4? judgedObjectColour;

public TestSceneComboCounter()
{
scoreProcessor = gameplayState.ScoreProcessor;
}

[BackgroundDependencyLoader]
private void load()
{
Dependencies.CacheAs<Player>(new TestPlayer
{
ShowingOverlayComponents = { BindTarget = showHud },
});
scoreProcessor.NewJudgement += result => gameplayState.ApplyResult(result);

Dependencies.CacheAs(gameplayState);
}

[SetUp]
public void SetUp() => Schedule(() =>
{
scoreProcessor = new ScoreProcessor(new CatchRuleset());

showHud.Value = true;

SetContents(_ => new CatchComboDisplay
SetContents(skin =>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(2.5f),
if (skin is LegacySkin)
{
return new LegacyCatchComboCounter
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
};
}

return Empty();
});
});

[Test]
public void TestCatchComboCounter()
{
AddRepeatStep("perform hit", () => performJudgement(HitResult.Great), 20);
AddStep("perform miss", () => performJudgement(HitResult.Miss));

AddStep("randomize judged object colour", () =>
AddRepeatStep("perform hit", () =>
{
judgedObjectColour = new Color4(
RNG.NextSingle(1f),
RNG.NextSingle(1f),
RNG.NextSingle(1f),
1f
);
});
if (judgedObjectColour == null || RNG.NextDouble() > 0.8)
{
judgedObjectColour = new Color4(
RNG.NextSingle(1f),
RNG.NextSingle(1f),
RNG.NextSingle(1f),
1f
);
}

AddStep("set hud to never show", () => showHud.Value = false);
AddRepeatStep("perform hit", () => performJudgement(HitResult.Great), 5);
performJudgement(HitResult.Great);
}, 20);

AddStep("set hud to show", () => showHud.Value = true);
AddRepeatStep("perform hit", () => performJudgement(HitResult.Great), 5);
AddStep("perform miss", () => performJudgement(HitResult.Miss));
}

private void performJudgement(HitResult type, Judgement? judgement = null)
{
var judgedObject = new DrawableFruit(new Fruit()) { AccentColour = { Value = judgedObjectColour } };
var judgedObject = new DrawableFruit(new ColourfulFruit(judgedObjectColour!.Value));

var result = new JudgementResult(judgedObject.HitObject, judgement ?? new Judgement()) { Type = type };
scoreProcessor.ApplyResult(result);
}

private class ColourfulFruit : Fruit, IHasComboInformation
{
private readonly Color4 colour;

public ColourfulFruit(Color4 colour)
{
this.colour = colour;
}

foreach (var counter in CreatedDrawables.Cast<CatchComboDisplay>())
counter.OnNewResult(judgedObject, result);
Color4 IHasComboInformation.GetComboColour(ISkin skin) => colour;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
</PropertyGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
<ProjectReference Include="..\osu.Game.Tests\osu.Game.Tests.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public CatchLegacySkinTransformer(ISkin skin)
switch (containerLookup.Lookup)
{
case GlobalSkinnableContainers.MainHUDComponents:
// todo: remove CatchSkinComponents.CatchComboCounter and refactor LegacyCatchComboCounter to be added here instead.
return new DefaultSkinComponentsContainer(container =>
{
var keyCounter = container.OfType<LegacyKeyCounterDisplay>().FirstOrDefault();
Expand All @@ -55,11 +54,20 @@ public CatchLegacySkinTransformer(ISkin skin)
keyCounter.Origin = Anchor.TopRight;
keyCounter.Position = new Vector2(0, -40) * 1.6f;
}

var combo = container.OfType<LegacyCatchComboCounter>().FirstOrDefault();

if (combo != null)
{
combo.Anchor = Anchor.CentreLeft;
combo.Origin = Anchor.Centre;
}
})
{
Children = new Drawable[]
{
new LegacyKeyCounterDisplay(),
new LegacyCatchComboCounter(),
}
};
}
Expand Down
Loading
Loading