mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 19:03:08 +08:00
Merge branch 'master' into hyperdash-full-catch-width
This commit is contained in:
commit
b98d4d9cff
@ -1,7 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.UI;
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
@ -38,7 +40,11 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
new Vector2(width, 0)
|
new Vector2(width, 0)
|
||||||
}),
|
}),
|
||||||
StartTime = i * 2000,
|
StartTime = i * 2000,
|
||||||
NewCombo = i % 8 == 0
|
NewCombo = i % 8 == 0,
|
||||||
|
Samples = new List<HitSampleInfo>(new[]
|
||||||
|
{
|
||||||
|
new HitSampleInfo { Bank = "normal", Name = "hitnormal", Volume = 100 }
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,19 +20,19 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation)))
|
foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation)))
|
||||||
AddStep($"show {rep}", () => SetContents(() => createDrawable(rep)));
|
AddStep($"show {rep}", () => SetContents(() => createDrawable(rep)));
|
||||||
|
|
||||||
AddStep("show droplet", () => SetContents(createDrawableDroplet));
|
AddStep("show droplet", () => SetContents(() => createDrawableDroplet()));
|
||||||
|
|
||||||
AddStep("show tiny droplet", () => SetContents(createDrawableTinyDroplet));
|
AddStep("show tiny droplet", () => SetContents(createDrawableTinyDroplet));
|
||||||
|
|
||||||
foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation)))
|
foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation)))
|
||||||
AddStep($"show hyperdash {rep}", () => SetContents(() => createDrawable(rep, true)));
|
AddStep($"show hyperdash {rep}", () => SetContents(() => createDrawable(rep, true)));
|
||||||
|
|
||||||
|
AddStep("show hyperdash droplet", () => SetContents(() => createDrawableDroplet(true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Drawable createDrawableTinyDroplet()
|
private Drawable createDrawableTinyDroplet()
|
||||||
{
|
{
|
||||||
var droplet = new TinyDroplet
|
var droplet = new TestCatchTinyDroplet
|
||||||
{
|
{
|
||||||
StartTime = Clock.CurrentTime,
|
|
||||||
Scale = 1.5f,
|
Scale = 1.5f,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,12 +47,12 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Drawable createDrawableDroplet()
|
private Drawable createDrawableDroplet(bool hyperdash = false)
|
||||||
{
|
{
|
||||||
var droplet = new Droplet
|
var droplet = new TestCatchDroplet
|
||||||
{
|
{
|
||||||
StartTime = Clock.CurrentTime,
|
|
||||||
Scale = 1.5f,
|
Scale = 1.5f,
|
||||||
|
HyperDashTarget = hyperdash ? new Banana() : null
|
||||||
};
|
};
|
||||||
|
|
||||||
return new DrawableDroplet(droplet)
|
return new DrawableDroplet(droplet)
|
||||||
@ -95,5 +95,21 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
|
|
||||||
public override FruitVisualRepresentation VisualRepresentation { get; }
|
public override FruitVisualRepresentation VisualRepresentation { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TestCatchDroplet : Droplet
|
||||||
|
{
|
||||||
|
public TestCatchDroplet()
|
||||||
|
{
|
||||||
|
StartTime = 1000000000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestCatchTinyDroplet : TinyDroplet
|
||||||
|
{
|
||||||
|
public TestCatchTinyDroplet()
|
||||||
|
{
|
||||||
|
StartTime = 1000000000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.UI;
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -31,6 +32,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing);
|
AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing);
|
||||||
AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing);
|
AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Catcher getCatcher() => Player.ChildrenOfType<CatcherArea>().First().MovableCatcher;
|
private Catcher getCatcher() => Player.ChildrenOfType<CatcherArea>().First().MovableCatcher;
|
||||||
@ -46,6 +49,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beatmap.ControlPointInfo.Add(0, new TimingControlPoint());
|
||||||
|
|
||||||
// Should produce a hyper-dash (edge case test)
|
// Should produce a hyper-dash (edge case test)
|
||||||
beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true });
|
beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true });
|
||||||
beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true });
|
beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true });
|
||||||
@ -63,6 +68,20 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
createObjects(() => new Fruit { X = right_x });
|
createObjects(() => new Fruit { X = right_x });
|
||||||
createObjects(() => new TestJuiceStream(left_x), 1);
|
createObjects(() => new TestJuiceStream(left_x), 1);
|
||||||
|
|
||||||
|
beatmap.ControlPointInfo.Add(startTime, new TimingControlPoint
|
||||||
|
{
|
||||||
|
BeatLength = 50
|
||||||
|
});
|
||||||
|
|
||||||
|
createObjects(() => new TestJuiceStream(left_x)
|
||||||
|
{
|
||||||
|
Path = new SliderPath(new[]
|
||||||
|
{
|
||||||
|
new PathControlPoint(Vector2.Zero),
|
||||||
|
new PathControlPoint(new Vector2(512, 0))
|
||||||
|
})
|
||||||
|
}, 1);
|
||||||
|
|
||||||
return beatmap;
|
return beatmap;
|
||||||
|
|
||||||
void createObjects(Func<CatchHitObject> createObject, int count = 3)
|
void createObjects(Func<CatchHitObject> createObject, int count = 3)
|
||||||
|
@ -27,6 +27,11 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
set => x = value;
|
set => x = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this object can be placed on the catcher's plate.
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool CanBePlated => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A random offset applied to <see cref="X"/>, set by the <see cref="CatchBeatmapProcessor"/>.
|
/// A random offset applied to <see cref="X"/>, set by the <see cref="CatchBeatmapProcessor"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -100,6 +105,14 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
|
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a single object that can be caught by the catcher.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class PalpableCatchHitObject : CatchHitObject
|
||||||
|
{
|
||||||
|
public override bool CanBePlated => true;
|
||||||
|
}
|
||||||
|
|
||||||
public enum FruitVisualRepresentation
|
public enum FruitVisualRepresentation
|
||||||
{
|
{
|
||||||
Pear,
|
Pear,
|
||||||
|
@ -15,14 +15,12 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||||
{
|
{
|
||||||
public abstract class PalpableCatchHitObject<TObject> : DrawableCatchHitObject<TObject>
|
public abstract class PalpableDrawableCatchHitObject<TObject> : DrawableCatchHitObject<TObject>
|
||||||
where TObject : CatchHitObject
|
where TObject : PalpableCatchHitObject
|
||||||
{
|
{
|
||||||
public override bool CanBePlated => true;
|
|
||||||
|
|
||||||
protected Container ScaleContainer { get; private set; }
|
protected Container ScaleContainer { get; private set; }
|
||||||
|
|
||||||
protected PalpableCatchHitObject(TObject hitObject)
|
protected PalpableDrawableCatchHitObject(TObject hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
@ -65,9 +63,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
|||||||
|
|
||||||
public abstract class DrawableCatchHitObject : DrawableHitObject<CatchHitObject>
|
public abstract class DrawableCatchHitObject : DrawableHitObject<CatchHitObject>
|
||||||
{
|
{
|
||||||
public virtual bool CanBePlated => false;
|
public virtual bool StaysOnPlate => HitObject.CanBePlated;
|
||||||
|
|
||||||
public virtual bool StaysOnPlate => CanBePlated;
|
|
||||||
|
|
||||||
public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale;
|
public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale;
|
||||||
|
|
||||||
|
@ -4,12 +4,11 @@
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces;
|
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||||
{
|
{
|
||||||
public class DrawableDroplet : PalpableCatchHitObject<Droplet>
|
public class DrawableDroplet : PalpableDrawableCatchHitObject<Droplet>
|
||||||
{
|
{
|
||||||
public override bool StaysOnPlate => false;
|
public override bool StaysOnPlate => false;
|
||||||
|
|
||||||
@ -21,11 +20,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
ScaleContainer.Child = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new Pulp
|
ScaleContainer.Child = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new DropletPiece());
|
||||||
{
|
|
||||||
Size = Size / 4,
|
|
||||||
AccentColour = { BindTarget = AccentColour }
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateInitialTransforms()
|
protected override void UpdateInitialTransforms()
|
||||||
|
@ -8,7 +8,7 @@ using osu.Game.Skinning;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||||
{
|
{
|
||||||
public class DrawableFruit : PalpableCatchHitObject<Fruit>
|
public class DrawableFruit : PalpableDrawableCatchHitObject<Fruit>
|
||||||
{
|
{
|
||||||
public DrawableFruit(Fruit h)
|
public DrawableFruit(Fruit h)
|
||||||
: base(h)
|
: base(h)
|
||||||
|
69
osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs
Normal file
69
osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces;
|
||||||
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||||
|
{
|
||||||
|
public class DropletPiece : CompositeDrawable
|
||||||
|
{
|
||||||
|
public DropletPiece()
|
||||||
|
{
|
||||||
|
Size = new Vector2(CatchHitObject.OBJECT_RADIUS / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(DrawableHitObject drawableObject)
|
||||||
|
{
|
||||||
|
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
|
||||||
|
var hitObject = drawableCatchObject.HitObject;
|
||||||
|
|
||||||
|
InternalChild = new Pulp
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
AccentColour = { BindTarget = drawableObject.AccentColour }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (hitObject.HyperDash)
|
||||||
|
{
|
||||||
|
AddInternal(new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Size = new Vector2(2f),
|
||||||
|
Depth = 1,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Circle
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
BorderColour = Catcher.DEFAULT_HYPER_DASH_COLOUR,
|
||||||
|
BorderThickness = 6,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
AlwaysPresent = true,
|
||||||
|
Alpha = 0.3f,
|
||||||
|
Blending = BlendingParameters.Additive,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
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.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -21,11 +20,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
|||||||
public const float RADIUS_ADJUST = 1.1f;
|
public const float RADIUS_ADJUST = 1.1f;
|
||||||
|
|
||||||
private Circle border;
|
private Circle border;
|
||||||
|
|
||||||
private CatchHitObject hitObject;
|
private CatchHitObject hitObject;
|
||||||
|
|
||||||
private readonly IBindable<Color4> accentColour = new Bindable<Color4>();
|
|
||||||
|
|
||||||
public FruitPiece()
|
public FruitPiece()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
@ -37,8 +33,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
|||||||
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
|
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
|
||||||
hitObject = drawableCatchObject.HitObject;
|
hitObject = drawableCatchObject.HitObject;
|
||||||
|
|
||||||
accentColour.BindTo(drawableCatchObject.AccentColour);
|
|
||||||
|
|
||||||
AddRangeInternal(new[]
|
AddRangeInternal(new[]
|
||||||
{
|
{
|
||||||
getFruitFor(drawableCatchObject.HitObject.VisualRepresentation),
|
getFruitFor(drawableCatchObject.HitObject.VisualRepresentation),
|
||||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables.Pieces
|
|||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
Radius = Size.X / 2,
|
Radius = DrawWidth / 2,
|
||||||
Colour = colour.NewValue.Darken(0.2f).Opacity(0.75f)
|
Colour = colour.NewValue.Darken(0.2f).Opacity(0.75f)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ using osu.Game.Rulesets.Judgements;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects
|
namespace osu.Game.Rulesets.Catch.Objects
|
||||||
{
|
{
|
||||||
public class Droplet : CatchHitObject
|
public class Droplet : PalpableCatchHitObject
|
||||||
{
|
{
|
||||||
public override Judgement CreateJudgement() => new CatchDropletJudgement();
|
public override Judgement CreateJudgement() => new CatchDropletJudgement();
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ using osu.Game.Rulesets.Judgements;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects
|
namespace osu.Game.Rulesets.Catch.Objects
|
||||||
{
|
{
|
||||||
public class Fruit : CatchHitObject
|
public class Fruit : PalpableCatchHitObject
|
||||||
{
|
{
|
||||||
public override Judgement CreateJudgement() => new CatchJudgement();
|
public override Judgement CreateJudgement() => new CatchJudgement();
|
||||||
}
|
}
|
||||||
|
@ -216,6 +216,9 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
/// <returns>Whether the catch is possible.</returns>
|
/// <returns>Whether the catch is possible.</returns>
|
||||||
public bool AttemptCatch(CatchHitObject fruit)
|
public bool AttemptCatch(CatchHitObject fruit)
|
||||||
{
|
{
|
||||||
|
if (!fruit.CanBePlated)
|
||||||
|
return false;
|
||||||
|
|
||||||
var halfCatchWidth = catchWidth * 0.5f;
|
var halfCatchWidth = catchWidth * 0.5f;
|
||||||
|
|
||||||
// this stuff wil disappear once we move fruit to non-relative coordinate space in the future.
|
// this stuff wil disappear once we move fruit to non-relative coordinate space in the future.
|
||||||
@ -226,9 +229,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
catchObjectPosition >= catcherPosition - halfCatchWidth &&
|
catchObjectPosition >= catcherPosition - halfCatchWidth &&
|
||||||
catchObjectPosition <= catcherPosition + halfCatchWidth;
|
catchObjectPosition <= catcherPosition + halfCatchWidth;
|
||||||
|
|
||||||
// only update hyperdash state if we are catching a fruit.
|
// only update hyperdash state if we are not catching a tiny droplet.
|
||||||
// exceptions are Droplets and JuiceStreams.
|
if (fruit is TinyDroplet) return validCatch;
|
||||||
if (!(fruit is Fruit)) return validCatch;
|
|
||||||
|
|
||||||
if (validCatch && fruit.HyperDash)
|
if (validCatch && fruit.HyperDash)
|
||||||
{
|
{
|
||||||
|
@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
lastPlateableFruit.OnLoadComplete += _ => action();
|
lastPlateableFruit.OnLoadComplete += _ => action();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.IsHit && fruit.CanBePlated)
|
if (result.IsHit && fruit.HitObject.CanBePlated)
|
||||||
{
|
{
|
||||||
// create a new (cloned) fruit to stay on the plate. the original is faded out immediately.
|
// create a new (cloned) fruit to stay on the plate. the original is faded out immediately.
|
||||||
var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject);
|
var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject);
|
||||||
|
@ -60,12 +60,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
Column = column.Key,
|
Column = column.Key,
|
||||||
StartTime = locations[i].startTime,
|
StartTime = locations[i].startTime,
|
||||||
Duration = duration,
|
Duration = duration,
|
||||||
Samples = locations[i].samples,
|
NodeSamples = new List<IList<HitSampleInfo>> { locations[i].samples, Array.Empty<HitSampleInfo>() }
|
||||||
NodeSamples = new List<IList<HitSampleInfo>>
|
|
||||||
{
|
|
||||||
locations[i].samples,
|
|
||||||
locations[i + 1].samples
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -20,9 +21,12 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
|||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
private readonly bool isLastColumn;
|
private readonly bool isLastColumn;
|
||||||
|
|
||||||
|
private Container borderLineContainer;
|
||||||
private Container lightContainer;
|
private Container lightContainer;
|
||||||
private Sprite light;
|
private Sprite light;
|
||||||
|
|
||||||
|
private float hitPosition;
|
||||||
|
|
||||||
public LegacyColumnBackground(bool isLastColumn)
|
public LegacyColumnBackground(bool isLastColumn)
|
||||||
{
|
{
|
||||||
this.isLastColumn = isLastColumn;
|
this.isLastColumn = isLastColumn;
|
||||||
@ -44,6 +48,9 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
|||||||
bool hasRightLine = rightLineWidth > 0 && skin.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m
|
bool hasRightLine = rightLineWidth > 0 && skin.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m
|
||||||
|| isLastColumn;
|
|| isLastColumn;
|
||||||
|
|
||||||
|
hitPosition = GetColumnSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.HitPosition)?.Value
|
||||||
|
?? Stage.HIT_TARGET_POSITION;
|
||||||
|
|
||||||
float lightPosition = GetColumnSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.LightPosition)?.Value
|
float lightPosition = GetColumnSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.LightPosition)?.Value
|
||||||
?? 0;
|
?? 0;
|
||||||
|
|
||||||
@ -63,6 +70,11 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = backgroundColour
|
Colour = backgroundColour
|
||||||
},
|
},
|
||||||
|
borderLineContainer = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
@ -80,6 +92,8 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
|||||||
Scale = new Vector2(0.740f, 1),
|
Scale = new Vector2(0.740f, 1),
|
||||||
Colour = lineColour,
|
Colour = lineColour,
|
||||||
Alpha = hasRightLine ? 1 : 0
|
Alpha = hasRightLine ? 1 : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
lightContainer = new Container
|
lightContainer = new Container
|
||||||
{
|
{
|
||||||
@ -109,11 +123,15 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
|||||||
{
|
{
|
||||||
lightContainer.Anchor = Anchor.TopCentre;
|
lightContainer.Anchor = Anchor.TopCentre;
|
||||||
lightContainer.Scale = new Vector2(1, -1);
|
lightContainer.Scale = new Vector2(1, -1);
|
||||||
|
|
||||||
|
borderLineContainer.Padding = new MarginPadding { Top = hitPosition };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lightContainer.Anchor = Anchor.BottomCentre;
|
lightContainer.Anchor = Anchor.BottomCentre;
|
||||||
lightContainer.Scale = Vector2.One;
|
lightContainer.Scale = Vector2.One;
|
||||||
|
|
||||||
|
borderLineContainer.Padding = new MarginPadding { Bottom = hitPosition };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
{
|
{
|
||||||
@ -10,11 +12,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
protected override bool UseOnlineAPI => true;
|
protected override bool UseOnlineAPI => true;
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private MusicController musicController { get; set; } = new MusicController();
|
||||||
|
|
||||||
public TestSceneMultiScreen()
|
public TestSceneMultiScreen()
|
||||||
{
|
{
|
||||||
Screens.Multi.Multiplayer multi = new Screens.Multi.Multiplayer();
|
Screens.Multi.Multiplayer multi = new Screens.Multi.Multiplayer();
|
||||||
|
|
||||||
AddStep(@"show", () => LoadScreen(multi));
|
AddStep("show", () => LoadScreen(multi));
|
||||||
|
AddUntilStep("wait for loaded", () => multi.IsLoaded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,22 +68,22 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestClearButtonOnBindings()
|
public void TestClearButtonOnBindings()
|
||||||
{
|
{
|
||||||
KeyBindingRow backBindingRow = null;
|
KeyBindingRow multiBindingRow = null;
|
||||||
|
|
||||||
AddStep("click back binding row", () =>
|
AddStep("click first row with two bindings", () =>
|
||||||
{
|
{
|
||||||
backBindingRow = panel.ChildrenOfType<KeyBindingRow>().ElementAt(10);
|
multiBindingRow = panel.ChildrenOfType<KeyBindingRow>().First(row => row.Defaults.Count() > 1);
|
||||||
InputManager.MoveMouseTo(backBindingRow);
|
InputManager.MoveMouseTo(multiBindingRow);
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
clickClearButton();
|
clickClearButton();
|
||||||
|
|
||||||
AddAssert("first binding cleared", () => string.IsNullOrEmpty(backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().Text.Text));
|
AddAssert("first binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().Text.Text));
|
||||||
|
|
||||||
AddStep("click second binding", () =>
|
AddStep("click second binding", () =>
|
||||||
{
|
{
|
||||||
var target = backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1);
|
var target = multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1);
|
||||||
|
|
||||||
InputManager.MoveMouseTo(target);
|
InputManager.MoveMouseTo(target);
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
@ -91,13 +91,13 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
|
|
||||||
clickClearButton();
|
clickClearButton();
|
||||||
|
|
||||||
AddAssert("second binding cleared", () => string.IsNullOrEmpty(backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1).Text.Text));
|
AddAssert("second binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1).Text.Text));
|
||||||
|
|
||||||
void clickClearButton()
|
void clickClearButton()
|
||||||
{
|
{
|
||||||
AddStep("click clear button", () =>
|
AddStep("click clear button", () =>
|
||||||
{
|
{
|
||||||
var clearButton = backBindingRow.ChildrenOfType<KeyBindingRow.ClearButton>().Single();
|
var clearButton = multiBindingRow.ChildrenOfType<KeyBindingRow.ClearButton>().Single();
|
||||||
|
|
||||||
InputManager.MoveMouseTo(clearButton);
|
InputManager.MoveMouseTo(clearButton);
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
@ -108,20 +108,20 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestClickRowSelectsFirstBinding()
|
public void TestClickRowSelectsFirstBinding()
|
||||||
{
|
{
|
||||||
KeyBindingRow backBindingRow = null;
|
KeyBindingRow multiBindingRow = null;
|
||||||
|
|
||||||
AddStep("click back binding row", () =>
|
AddStep("click first row with two bindings", () =>
|
||||||
{
|
{
|
||||||
backBindingRow = panel.ChildrenOfType<KeyBindingRow>().ElementAt(10);
|
multiBindingRow = panel.ChildrenOfType<KeyBindingRow>().First(row => row.Defaults.Count() > 1);
|
||||||
InputManager.MoveMouseTo(backBindingRow);
|
InputManager.MoveMouseTo(multiBindingRow);
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("first binding selected", () => backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().IsBinding);
|
AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().IsBinding);
|
||||||
|
|
||||||
AddStep("click second binding", () =>
|
AddStep("click second binding", () =>
|
||||||
{
|
{
|
||||||
var target = backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1);
|
var target = multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1);
|
||||||
|
|
||||||
InputManager.MoveMouseTo(target);
|
InputManager.MoveMouseTo(target);
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
@ -129,12 +129,12 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
|
|
||||||
AddStep("click back binding row", () =>
|
AddStep("click back binding row", () =>
|
||||||
{
|
{
|
||||||
backBindingRow = panel.ChildrenOfType<KeyBindingRow>().ElementAt(10);
|
multiBindingRow = panel.ChildrenOfType<KeyBindingRow>().ElementAt(10);
|
||||||
InputManager.MoveMouseTo(backBindingRow);
|
InputManager.MoveMouseTo(multiBindingRow);
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("first binding selected", () => backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().IsBinding);
|
AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().IsBinding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,8 @@ namespace osu.Game.Storyboards.Drawables
|
|||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
Channel?.Stop();
|
Channel?.Stop();
|
||||||
|
Channel = null;
|
||||||
|
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user