mirror of
https://github.com/ppy/osu.git
synced 2026-06-03 02:31:25 +08:00
Merge pull request #34606 from cl8n/sliderpoint
Add skin support for sliderpoint10 and sliderpoint30
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,160 @@
|
||||
// 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.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
public partial class TestSceneDrawableJudgementSliderTicks : OsuSkinnableTestScene
|
||||
{
|
||||
private bool classic;
|
||||
private readonly JudgementPooler<DrawableOsuJudgement>[] judgementPools;
|
||||
|
||||
public TestSceneDrawableJudgementSliderTicks()
|
||||
{
|
||||
judgementPools = new JudgementPooler<DrawableOsuJudgement>[Rows * Cols];
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
int cellIndex = 0;
|
||||
|
||||
SetContents(_ =>
|
||||
{
|
||||
var container = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
judgementPools[cellIndex] = new JudgementPooler<DrawableOsuJudgement>(new[]
|
||||
{
|
||||
HitResult.Great,
|
||||
HitResult.Miss,
|
||||
HitResult.LargeTickHit,
|
||||
HitResult.SliderTailHit,
|
||||
HitResult.LargeTickMiss,
|
||||
HitResult.IgnoreMiss,
|
||||
}),
|
||||
new GridContainer
|
||||
{
|
||||
Padding = new MarginPadding { Top = 26f },
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
|
||||
ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
|
||||
Content =
|
||||
new[]
|
||||
{
|
||||
new[]
|
||||
{
|
||||
Empty(),
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "hit",
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "miss",
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
},
|
||||
},
|
||||
}.Concat(new[]
|
||||
{
|
||||
"head",
|
||||
"tick",
|
||||
"repeat",
|
||||
"tail",
|
||||
"slider",
|
||||
}.Select(label => new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = label,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
},
|
||||
new Container<DrawableOsuJudgement> { RelativeSizeAxes = Axes.Both },
|
||||
new Container<DrawableOsuJudgement> { RelativeSizeAxes = Axes.Both },
|
||||
})).ToArray(),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
cellIndex++;
|
||||
|
||||
return container;
|
||||
});
|
||||
|
||||
AddToggleStep("Toggle classic behaviour", c => classic = c);
|
||||
|
||||
AddStep("Show judgements", createAllJudgements);
|
||||
}
|
||||
|
||||
private void createAllJudgements()
|
||||
{
|
||||
for (int cellIndex = 0; cellIndex < Rows * Cols; cellIndex++)
|
||||
{
|
||||
var slider = new Slider { StartTime = Time.Current, ClassicSliderBehaviour = classic };
|
||||
slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||
|
||||
var drawableHitObjects = new DrawableOsuHitObject[]
|
||||
{
|
||||
new DrawableSliderHead(new SliderHeadCircle { StartTime = Time.Current, ClassicSliderBehaviour = classic }),
|
||||
new DrawableSliderTick(new SliderTick { StartTime = Time.Current }),
|
||||
new DrawableSliderRepeat(new SliderRepeat(slider) { StartTime = Time.Current }),
|
||||
new DrawableSliderTail(new SliderTailCircle(slider) { StartTime = Time.Current, ClassicSliderBehaviour = classic }),
|
||||
new DrawableSlider(slider),
|
||||
};
|
||||
|
||||
var containers = Cell(cellIndex).ChildrenOfType<Container<DrawableOsuJudgement>>().ToArray();
|
||||
|
||||
for (int i = 0; i < drawableHitObjects.Length; i++)
|
||||
{
|
||||
createJudgement(judgementPools[cellIndex], containers[i * 2], drawableHitObjects[i], true);
|
||||
createJudgement(judgementPools[cellIndex], containers[i * 2 + 1], drawableHitObjects[i], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createJudgement(JudgementPooler<DrawableOsuJudgement> pool, Container<DrawableOsuJudgement> container, DrawableOsuHitObject drawableHitObject, bool hit)
|
||||
{
|
||||
container.Clear(false);
|
||||
|
||||
if (!drawableHitObject.DisplayResult)
|
||||
return;
|
||||
|
||||
var hitObject = drawableHitObject.HitObject;
|
||||
var result = new OsuJudgementResult(hitObject, hitObject.Judgement)
|
||||
{
|
||||
Type = hit ? hitObject.Judgement.MaxResult : hitObject.Judgement.MinResult,
|
||||
};
|
||||
|
||||
var judgement = pool.Get(result.Type, d =>
|
||||
{
|
||||
d.Anchor = Anchor.Centre;
|
||||
d.Origin = Anchor.Centre;
|
||||
d.Scale = new Vector2(0.7f);
|
||||
d.Apply(result, null);
|
||||
});
|
||||
|
||||
if (judgement != null)
|
||||
container.Add(judgement);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
[Resolved]
|
||||
private OsuConfigManager config { get; set; } = null!;
|
||||
|
||||
private Vector2 screenSpacePosition;
|
||||
private Vector2? screenSpacePosition;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
@@ -65,7 +65,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
Lighting.ResetAnimation();
|
||||
Lighting.SetColourFrom(this, Result);
|
||||
Position = Parent!.ToLocalSpace(screenSpacePosition);
|
||||
|
||||
if (screenSpacePosition != null)
|
||||
Position = Parent!.ToLocalSpace(screenSpacePosition.Value);
|
||||
}
|
||||
|
||||
protected override void ApplyHitAnimations()
|
||||
@@ -87,7 +89,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
base.ApplyHitAnimations();
|
||||
}
|
||||
|
||||
protected override Drawable CreateDefaultJudgement(HitResult result) => new OsuJudgementPiece(result);
|
||||
protected override Drawable CreateDefaultJudgement(HitResult result) =>
|
||||
// Tick hits don't show a judgement by default
|
||||
result.IsHit() && result.IsTick() ? Empty() : new OsuJudgementPiece(result);
|
||||
|
||||
private partial class OsuJudgementPiece : DefaultJudgementPiece
|
||||
{
|
||||
|
||||
@@ -16,17 +16,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
public DrawableSlider DrawableSlider => (DrawableSlider)ParentHitObject;
|
||||
|
||||
public override bool DisplayResult
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HitObject?.ClassicSliderBehaviour == true)
|
||||
return false;
|
||||
|
||||
return base.DisplayResult;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IBindable<int> pathVersion = new Bindable<int>();
|
||||
|
||||
protected override OsuSkinComponents CirclePieceComponent => OsuSkinComponents.SliderHeadHitCircle;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@@ -42,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
if (targetJudgement == null || targetResult == null)
|
||||
Colour = Color4.White;
|
||||
else
|
||||
Colour = targetResult.IsHit ? targetJudgement.AccentColour : Color4.Transparent;
|
||||
Colour = targetResult.IsHit && !targetResult.Type.IsTick() ? targetJudgement.AccentColour : Color4.Transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case HitResult.LargeTickHit:
|
||||
case HitResult.SliderTailHit:
|
||||
return null;
|
||||
|
||||
case HitResult.IgnoreMiss:
|
||||
case HitResult.LargeTickMiss:
|
||||
return new ArgonJudgementPieceSliderTickMiss(result);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
{
|
||||
public partial class LegacyJudgementPieceSliderTickHit : Sprite, IAnimatableJudgement
|
||||
{
|
||||
public void PlayAnimation()
|
||||
{
|
||||
// https://github.com/peppy/osu-stable-reference/blob/0e91e49bc83fe8b21c3ba5f1eb2d5d06456eae84/osu!/GameModes/Play/Rulesets/Ruleset.cs#L804-L806
|
||||
this.MoveToOffset(new Vector2(0, -10), 300, Easing.Out)
|
||||
.Then()
|
||||
.FadeOut(60);
|
||||
}
|
||||
|
||||
public Drawable GetAboveHitObjectsProxiedContent() => CreateProxy();
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,9 @@ using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
@@ -115,6 +117,39 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
|
||||
return null;
|
||||
|
||||
case SkinComponentLookup<HitResult> resultComponent:
|
||||
switch (resultComponent.Component)
|
||||
{
|
||||
case HitResult.LargeTickHit:
|
||||
case HitResult.SliderTailHit:
|
||||
if (getSliderPointTexture(resultComponent.Component) is Texture texture)
|
||||
return new LegacyJudgementPieceSliderTickHit { Texture = texture };
|
||||
|
||||
break;
|
||||
|
||||
// If the corresponding hit result displays a judgement and the miss texture isn't provided by this skin, don't look up the miss texture from any further skins.
|
||||
case HitResult.LargeTickMiss:
|
||||
case HitResult.IgnoreMiss:
|
||||
if (getSliderPointTexture(resultComponent.Component == HitResult.LargeTickMiss
|
||||
? HitResult.LargeTickHit
|
||||
: HitResult.SliderTailHit) != null)
|
||||
return base.GetDrawableComponent(lookup) ?? Drawable.Empty();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return base.GetDrawableComponent(lookup);
|
||||
|
||||
Texture? getSliderPointTexture(HitResult result)
|
||||
{
|
||||
// https://github.com/peppy/osu-stable-reference/blob/0e91e49bc83fe8b21c3ba5f1eb2d5d06456eae84/osu!/GameModes/Play/Rulesets/Ruleset.cs#L799
|
||||
if (GetConfig<SkinConfiguration.LegacySetting, decimal>(SkinConfiguration.LegacySetting.Version)?.Value < 2m)
|
||||
// Note that osu!stable used sliderpoint30 for heads and repeats, and sliderpoint10 for ticks, but the mapping is intentionally changed here so that each texture represents one type of HitResult.
|
||||
return GetTexture(result == HitResult.LargeTickHit ? "sliderpoint30" : "sliderpoint10");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
case OsuSkinComponentLookup osuComponent:
|
||||
switch (osuComponent.Component)
|
||||
{
|
||||
|
||||
@@ -81,6 +81,8 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
HitResult.Ok,
|
||||
HitResult.Meh,
|
||||
HitResult.Miss,
|
||||
HitResult.LargeTickHit,
|
||||
HitResult.SliderTailHit,
|
||||
HitResult.LargeTickMiss,
|
||||
HitResult.IgnoreMiss,
|
||||
}, onJudgementLoaded));
|
||||
|
||||
Reference in New Issue
Block a user