1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:27:29 +08:00

Merge branch 'master' into mania-key-expand-mobile

This commit is contained in:
Bartłomiej Dach 2023-11-02 11:59:01 +01:00
commit 998d709331
No known key found for this signature in database
4 changed files with 60 additions and 58 deletions

View File

@ -255,16 +255,6 @@ namespace osu.Game.Rulesets.Mania
case ModType.Conversion:
return new Mod[]
{
new MultiMod(new ManiaModKey4(),
new ManiaModKey5(),
new ManiaModKey6(),
new ManiaModKey7(),
new ManiaModKey8(),
new ManiaModKey9(),
new ManiaModKey10(),
new ManiaModKey1(),
new ManiaModKey2(),
new ManiaModKey3()),
new ManiaModRandom(),
new ManiaModDualStages(),
new ManiaModMirror(),
@ -272,7 +262,19 @@ namespace osu.Game.Rulesets.Mania
new ManiaModClassic(),
new ManiaModInvert(),
new ManiaModConstantSpeed(),
new ManiaModHoldOff()
new ManiaModHoldOff(),
new MultiMod(
new ManiaModKey1(),
new ManiaModKey2(),
new ManiaModKey3(),
new ManiaModKey4(),
new ManiaModKey5(),
new ManiaModKey6(),
new ManiaModKey7(),
new ManiaModKey8(),
new ManiaModKey9(),
new ManiaModKey10()
),
};
case ModType.Automation:

View File

@ -2,11 +2,9 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
@ -22,6 +20,7 @@ using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Scoring;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Mods
{
@ -90,21 +89,18 @@ namespace osu.Game.Rulesets.Osu.Mods
break;
default:
addBubble();
BubbleDrawable bubble = bubblePool.Get();
bubble.WasHit = drawable.IsHit;
bubble.Position = getPosition(drawableOsuHitObject);
bubble.AccentColour = drawable.AccentColour.Value;
bubble.InitialSize = new Vector2(bubbleSize);
bubble.FadeTime = bubbleFade;
bubble.MaxSize = maxSize;
bubbleContainer.Add(bubble);
break;
}
void addBubble()
{
BubbleDrawable bubble = bubblePool.Get();
bubble.DrawableOsuHitObject = drawableOsuHitObject;
bubble.InitialSize = new Vector2(bubbleSize);
bubble.FadeTime = bubbleFade;
bubble.MaxSize = maxSize;
bubbleContainer.Add(bubble);
}
};
drawableObject.OnRevertResult += (drawable, _) =>
@ -118,18 +114,38 @@ namespace osu.Game.Rulesets.Osu.Mods
};
}
private Vector2 getPosition(DrawableOsuHitObject drawableObject)
{
switch (drawableObject)
{
// SliderHeads are derived from HitCircles,
// so we must handle them before to avoid them using the wrong positioning logic
case DrawableSliderHead:
return drawableObject.HitObject.Position;
// Using hitobject position will cause issues with HitCircle placement due to stack leniency.
case DrawableHitCircle:
return drawableObject.Position;
default:
return drawableObject.HitObject.Position;
}
}
#region Pooled Bubble drawable
private partial class BubbleDrawable : PoolableDrawable
{
public DrawableOsuHitObject? DrawableOsuHitObject { get; set; }
public Vector2 InitialSize { get; set; }
public float MaxSize { get; set; }
public double FadeTime { get; set; }
public bool WasHit { get; set; }
public Color4 AccentColour { get; set; }
private readonly Box colourBox;
private readonly CircularContainer content;
@ -157,15 +173,12 @@ namespace osu.Game.Rulesets.Osu.Mods
protected override void PrepareForUse()
{
Debug.Assert(DrawableOsuHitObject.IsNotNull());
Colour = DrawableOsuHitObject.IsHit ? Colour4.White : Colour4.Black;
Colour = WasHit ? Colour4.White : Colour4.Black;
Scale = new Vector2(1);
Position = getPosition(DrawableOsuHitObject);
Size = InitialSize;
//We want to fade to a darker colour to avoid colours such as white hiding the "ripple" effect.
ColourInfo colourDarker = DrawableOsuHitObject.AccentColour.Value.Darken(0.1f);
ColourInfo colourDarker = AccentColour.Darken(0.1f);
// The absolute length of the bubble's animation, can be used in fractions for animations of partial length
double duration = 1700 + Math.Pow(FadeTime, 1.07f);
@ -178,7 +191,7 @@ namespace osu.Game.Rulesets.Osu.Mods
.ScaleTo(MaxSize * 1.5f, duration * 0.2f, Easing.OutQuint)
.FadeOut(duration * 0.2f, Easing.OutCirc).Expire();
if (!DrawableOsuHitObject.IsHit) return;
if (!WasHit) return;
content.BorderThickness = InitialSize.X / 3.5f;
content.BorderColour = Colour4.White;
@ -192,24 +205,6 @@ namespace osu.Game.Rulesets.Osu.Mods
// Avoids transparency overlap issues during the bubble "pop"
.TransformTo(nameof(BorderThickness), 0f);
}
private Vector2 getPosition(DrawableOsuHitObject drawableObject)
{
switch (drawableObject)
{
// SliderHeads are derived from HitCircles,
// so we must handle them before to avoid them using the wrong positioning logic
case DrawableSliderHead:
return drawableObject.HitObject.Position;
// Using hitobject position will cause issues with HitCircle placement due to stack leniency.
case DrawableHitCircle:
return drawableObject.Position;
default:
return drawableObject.HitObject.Position;
}
}
}
#endregion

View File

@ -275,6 +275,15 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (spinningSample != null && spinnerFrequencyModulate)
spinningSample.Frequency.Value = spinning_sample_modulated_base_frequency + Progress;
// Ticks can theoretically be judged at any point in the spinner's duration.
// A tick must be alive to correctly play back samples,
// but for performance reasons, we only want to keep the next tick alive.
var next = NestedHitObjects.FirstOrDefault(h => !h.Judged);
// See default `LifetimeStart` as set in `DrawableSpinnerTick`.
if (next?.LifetimeStart == double.MaxValue)
next.LifetimeStart = HitObject.StartTime;
}
protected override void UpdateAfterChildren()

View File

@ -11,8 +11,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public override bool DisplayResult => false;
protected DrawableSpinner DrawableSpinner => (DrawableSpinner)ParentHitObject;
public DrawableSpinnerTick()
: this(null)
{
@ -29,10 +27,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
base.OnApply();
// the tick can be theoretically judged at any point in the spinner's duration,
// so it must be alive throughout the spinner's entire lifetime.
// this mostly matters for correct sample playback.
LifetimeStart = DrawableSpinner.HitObject.StartTime;
// Lifetime will be managed by `DrawableSpinner`.
LifetimeStart = double.MaxValue;
}
/// <summary>