Merge pull request #17622 from frenzibyte/taiko-target-classic-position

Replicate osu!(stable)'s hit target position with "Classic" mod
This commit is contained in:
Dean Herbert
2022-07-20 20:08:00 +09:00
committed by GitHub
5 changed files with 221 additions and 156 deletions

View File

@ -0,0 +1,19 @@
// 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.Rulesets.Taiko.Mods;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Taiko.Tests
{
public class TestSceneTaikoPlayerLegacySkin : LegacySkinPlayerTestScene
{
protected override Ruleset CreatePlayerRuleset() => new TaikoRuleset();
protected override TestPlayer CreatePlayer(Ruleset ruleset)
{
SelectedMods.Value = new[] { new TaikoModClassic() };
return base.CreatePlayer(ruleset);
}
}
}

View File

@ -18,6 +18,9 @@ namespace osu.Game.Rulesets.Taiko.Mods
{ {
drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset; drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset;
drawableTaikoRuleset.LockPlayfieldAspect.Value = false; drawableTaikoRuleset.LockPlayfieldAspect.Value = false;
var playfield = (TaikoPlayfield)drawableRuleset.Playfield;
playfield.ClassicHitTargetPosition.Value = true;
} }
public void Update(Playfield playfield) public void Update(Playfield playfield)

View File

@ -22,13 +22,14 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
/// </summary> /// </summary>
internal class LegacyInputDrum : Container internal class LegacyInputDrum : Container
{ {
private Container content;
private LegacyHalfDrum left; private LegacyHalfDrum left;
private LegacyHalfDrum right; private LegacyHalfDrum right;
private Container content;
public LegacyInputDrum() public LegacyInputDrum()
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Y;
AutoSizeAxes = Axes.X;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -14,6 +14,7 @@ using osu.Framework.Input.Events;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Screens.Ranking;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK; using osuTK;
@ -33,7 +34,8 @@ namespace osu.Game.Rulesets.Taiko.UI
{ {
sampleTriggerSource = new DrumSampleTriggerSource(hitObjectContainer); sampleTriggerSource = new DrumSampleTriggerSource(hitObjectContainer);
RelativeSizeAxes = Axes.Both; AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -41,12 +43,32 @@ namespace osu.Game.Rulesets.Taiko.UI
{ {
Children = new Drawable[] Children = new Drawable[]
{ {
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.InputDrum), _ => new Container new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum())
{ {
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
},
sampleTriggerSource
};
}
private class DefaultInputDrum : AspectContainer
{
public DefaultInputDrum()
{
RelativeSizeAxes = Axes.Y;
}
[BackgroundDependencyLoader]
private void load()
{
InternalChild = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Scale = new Vector2(0.9f), Scale = new Vector2(0.9f),
Children = new Drawable[] Children = new[]
{ {
new TaikoHalfDrum(false) new TaikoHalfDrum(false)
{ {
@ -71,8 +93,6 @@ namespace osu.Game.Rulesets.Taiko.UI
CentreAction = TaikoAction.RightCentre CentreAction = TaikoAction.RightCentre
} }
} }
}),
sampleTriggerSource
}; };
} }
@ -199,4 +219,5 @@ namespace osu.Game.Rulesets.Taiko.UI
} }
} }
} }
}
} }

View File

@ -7,6 +7,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Pooling; using osu.Framework.Graphics.Pooling;
@ -34,6 +35,11 @@ namespace osu.Game.Rulesets.Taiko.UI
/// </summary> /// </summary>
public const float DEFAULT_HEIGHT = 200; public const float DEFAULT_HEIGHT = 200;
/// <summary>
/// Whether the hit target should be nudged further towards the left area, matching the stable "classic" position.
/// </summary>
public Bindable<bool> ClassicHitTargetPosition = new BindableBool();
private Container<HitExplosion> hitExplosionContainer; private Container<HitExplosion> hitExplosionContainer;
private Container<KiaiHitExplosion> kiaiExplosionContainer; private Container<KiaiHitExplosion> kiaiExplosionContainer;
private JudgementContainer<DrawableTaikoJudgement> judgementContainer; private JudgementContainer<DrawableTaikoJudgement> judgementContainer;
@ -45,8 +51,8 @@ namespace osu.Game.Rulesets.Taiko.UI
private readonly IDictionary<HitResult, HitExplosionPool> explosionPools = new Dictionary<HitResult, HitExplosionPool>(); private readonly IDictionary<HitResult, HitExplosionPool> explosionPools = new Dictionary<HitResult, HitExplosionPool>();
private ProxyContainer topLevelHitContainer; private ProxyContainer topLevelHitContainer;
private InputDrum inputDrum;
private Container rightArea; private Container rightArea;
private Container leftArea;
/// <remarks> /// <remarks>
/// <see cref="Playfield.AddNested"/> is purposefully not called on this to prevent i.e. being able to interact /// <see cref="Playfield.AddNested"/> is purposefully not called on this to prevent i.e. being able to interact
@ -54,14 +60,43 @@ namespace osu.Game.Rulesets.Taiko.UI
/// </remarks> /// </remarks>
private BarLinePlayfield barLinePlayfield; private BarLinePlayfield barLinePlayfield;
private Container hitTargetOffsetContent; private Container playfieldContent;
private Container playfieldOverlay;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
inputDrum = new InputDrum(HitObjectContainer)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y,
};
InternalChildren = new[] InternalChildren = new[]
{ {
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()), new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()),
new Container
{
Name = "Left overlay",
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
BorderColour = colours.Gray0,
Children = new[]
{
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()),
inputDrum.CreateProxy(),
}
},
mascot = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Mascot), _ => Empty())
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.TopLeft,
RelativePositionAxes = Axes.Y,
RelativeSizeAxes = Axes.None,
Y = 0.2f
},
rightArea = new Container rightArea = new Container
{ {
Name = "Right area", Name = "Right area",
@ -71,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko.UI
{ {
new Container new Container
{ {
Name = "Masked elements before hit objects", Name = "Elements before hit objects",
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit, FillMode = FillMode.Fit,
Children = new[] Children = new[]
@ -86,22 +121,28 @@ namespace osu.Game.Rulesets.Taiko.UI
} }
} }
}, },
hitTargetOffsetContent = new Container new Container
{
Name = "Masked hit objects content",
RelativeSizeAxes = Axes.Both,
Masking = true,
Child = playfieldContent = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
barLinePlayfield = new BarLinePlayfield(), barLinePlayfield = new BarLinePlayfield(),
new Container HitObjectContainer,
}
}
},
playfieldOverlay = new Container
{ {
Name = "Hit objects", Name = "Elements after hit objects",
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
HitObjectContainer, drumRollHitContainer = new DrumRollHitContainer(),
drumRollHitContainer = new DrumRollHitContainer()
}
},
kiaiExplosionContainer = new Container<KiaiHitExplosion> kiaiExplosionContainer = new Container<KiaiHitExplosion>
{ {
Name = "Kiai hit explosions", Name = "Kiai hit explosions",
@ -117,36 +158,15 @@ namespace osu.Game.Rulesets.Taiko.UI
}, },
} }
}, },
leftArea = new Container
{
Name = "Left overlay",
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
BorderColour = colours.Gray0,
Children = new Drawable[]
{
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()),
new InputDrum(HitObjectContainer)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
},
}
},
mascot = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Mascot), _ => Empty())
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.TopLeft,
RelativePositionAxes = Axes.Y,
RelativeSizeAxes = Axes.None,
Y = 0.2f
},
topLevelHitContainer = new ProxyContainer topLevelHitContainer = new ProxyContainer
{ {
Name = "Top level hit objects", Name = "Top level hit objects",
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
drumRollHitContainer.CreateProxy(), drumRollHitContainer.CreateProxy(),
// this is added at the end of the hierarchy to receive input before taiko objects.
// but is proxied below everything to not cover visual effects such as hit explosions.
inputDrum,
}; };
RegisterPool<Hit, DrawableHit>(50); RegisterPool<Hit, DrawableHit>(50);
@ -193,8 +213,9 @@ namespace osu.Game.Rulesets.Taiko.UI
// Padding is required to be updated for elements which are based on "absolute" X sized elements. // Padding is required to be updated for elements which are based on "absolute" X sized elements.
// This is basically allowing for correct alignment as relative pieces move around them. // This is basically allowing for correct alignment as relative pieces move around them.
rightArea.Padding = new MarginPadding { Left = leftArea.DrawWidth }; rightArea.Padding = new MarginPadding { Left = inputDrum.Width };
hitTargetOffsetContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; playfieldContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
playfieldOverlay.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
mascot.Scale = new Vector2(DrawHeight / DEFAULT_HEIGHT); mascot.Scale = new Vector2(DrawHeight / DEFAULT_HEIGHT);
} }