1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-15 09:42:57 +08:00

Merge branch 'master' into user-profile-recent

This commit is contained in:
Dean Herbert 2018-02-28 23:49:33 +09:00 committed by GitHub
commit eacb9ba743
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 202 additions and 102 deletions

@ -1 +1 @@
Subproject commit 9a773e62eb246206b918ba4fccf9f2507aaa4595
Subproject commit 500a791577979669e47eece699d5bd8b9068ee4b

View File

@ -4,6 +4,7 @@
using System;
using System.IO;
using System.Linq;
using System.Runtime;
using osu.Framework;
using osu.Framework.Platform;
using osu.Game.IPC;
@ -15,6 +16,9 @@ namespace osu.Desktop
[STAThread]
public static int Main(string[] args)
{
if (!RuntimeInfo.IsMono)
useMulticoreJit();
// Back up the cwd before DesktopGameHost changes it
var cwd = Environment.CurrentDirectory;
@ -44,8 +48,16 @@ namespace osu.Desktop
break;
}
}
return 0;
}
}
private static void useMulticoreJit()
{
var directory = Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Profiles"));
ProfileOptimization.SetProfileRoot(directory.FullName);
ProfileOptimization.StartProfile("Startup.Profile");
}
}
}

View File

@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
StartTime = lastTickTime,
ComboColour = ComboColour,
X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH,
X = X + Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH,
Samples = new List<SampleInfo>(Samples.Select(s => new SampleInfo
{
Bank = s.Bank,
@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
StartTime = spanStartTime + t,
ComboColour = ComboColour,
X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH,
X = X + Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH,
Samples = new List<SampleInfo>(Samples.Select(s => new SampleInfo
{
Bank = s.Bank,
@ -120,14 +120,14 @@ namespace osu.Game.Rulesets.Catch.Objects
Samples = Samples,
ComboColour = ComboColour,
StartTime = spanStartTime + spanDuration,
X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
X = X + Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
});
}
}
public double EndTime => StartTime + this.SpanCount() * Curve.Distance / Velocity;
public float EndX => Curve.PositionAt(this.ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH;
public float EndX => X + this.CurvePositionAt(1).X / CatchPlayfield.BASE_WIDTH;
public double Duration => EndTime - StartTime;

View File

@ -78,8 +78,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
bool isRepeatAtEnd = repeatPoint.RepeatIndex % 2 == 0;
List<Vector2> curve = drawableSlider.Body.CurrentCurve;
var positionOnCurve = isRepeatAtEnd ? end : start;
Position = positionOnCurve + drawableSlider.HitObject.StackOffset;
Position = isRepeatAtEnd ? end : start;
if (curve.Count < 2)
return;
@ -90,10 +89,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
// find the next vector2 in the curve which is not equal to our current position to infer a rotation.
for (int i = searchStart; i >= 0 && i < curve.Count; i += direction)
{
if (curve[i] == positionOnCurve)
if (curve[i] == Position)
continue;
Rotation = MathHelper.RadiansToDegrees((float)Math.Atan2(curve[i].Y - positionOnCurve.Y, curve[i].X - positionOnCurve.X));
Rotation = MathHelper.RadiansToDegrees((float)Math.Atan2(curve[i].Y - Position.Y, curve[i].X - Position.X));
break;
}
}

View File

@ -12,6 +12,7 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Framework.Graphics.Primitives;
using osu.Game.Configuration;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
@ -30,6 +31,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
slider = s;
Position = s.StackedPosition;
DrawableSliderTail tail;
Container<DrawableSliderTick> ticks;
Container<DrawableRepeatPoint> repeatPoints;
@ -39,20 +42,20 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Body = new SliderBody(s)
{
AccentColour = AccentColour,
Position = s.StackedPosition,
PathWidth = s.Scale * 64,
},
ticks = new Container<DrawableSliderTick>(),
repeatPoints = new Container<DrawableRepeatPoint>(),
ticks = new Container<DrawableSliderTick> { RelativeSizeAxes = Axes.Both },
repeatPoints = new Container<DrawableRepeatPoint> { RelativeSizeAxes = Axes.Both },
Ball = new SliderBall(s)
{
BypassAutoSizeAxes = Axes.Both,
Scale = new Vector2(s.Scale),
AccentColour = AccentColour,
AlwaysPresent = true,
Alpha = 0
},
HeadCircle = new DrawableHitCircle(s.HeadCircle),
tail = new DrawableSliderTail(s.TailCircle)
HeadCircle = new DrawableHitCircle(s.HeadCircle) { Position = s.HeadCircle.Position - s.Position },
tail = new DrawableSliderTail(s.TailCircle) { Position = s.TailCircle.Position - s.Position }
};
components.Add(Body);
@ -65,10 +68,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
foreach (var tick in s.NestedHitObjects.OfType<SliderTick>())
{
var drawableTick = new DrawableSliderTick(tick)
{
Position = tick.StackedPosition
};
var drawableTick = new DrawableSliderTick(tick) { Position = tick.Position - s.Position };
ticks.Add(drawableTick);
components.Add(drawableTick);
@ -77,10 +77,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
foreach (var repeatPoint in s.NestedHitObjects.OfType<RepeatPoint>())
{
var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this)
{
Position = repeatPoint.StackedPosition
};
var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this) { Position = repeatPoint.Position - s.Position };
repeatPoints.Add(drawableRepeatPoint);
components.Add(drawableRepeatPoint);
@ -107,11 +104,22 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
//todo: we probably want to reconsider this before adding scoring, but it looks and feels nice.
if (!HeadCircle.IsHit)
HeadCircle.Position = slider.StackedPositionAt(completionProgress);
HeadCircle.Position = slider.CurvePositionAt(completionProgress);
foreach (var c in components.OfType<ISliderProgress>()) c.UpdateProgress(completionProgress);
foreach (var c in components.OfType<ITrackSnaking>()) c.UpdateSnakingPosition(slider.Curve.PositionAt(Body.SnakedStart ?? 0), slider.Curve.PositionAt(Body.SnakedEnd ?? 0));
foreach (var t in components.OfType<IRequireTracking>()) t.Tracking = Ball.Tracking;
Size = Body.Size;
OriginPosition = Body.PathOffset;
if (DrawSize != Vector2.Zero)
{
var childAnchorPosition = Vector2.Divide(OriginPosition, DrawSize);
foreach (var obj in NestedHitObjects)
obj.RelativeAnchorPosition = childAnchorPosition;
Ball.RelativeAnchorPosition = childAnchorPosition;
}
}
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
@ -154,6 +162,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
this.FadeOut(fade_out_time, Easing.OutQuint).Expire();
}
Expire(true);
}
public Drawable ProxiedLayer => HeadCircle.ApproachCircle;

View File

@ -19,8 +19,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public DrawableSliderTail(HitCircle hitCircle)
: base(hitCircle)
{
AlwaysPresent = true;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
FillMode = FillMode.Fit;
AlwaysPresent = true;
}
protected override void CheckForJudgements(bool userTriggered, double timeOffset)

View File

@ -6,6 +6,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Game.Rulesets.Objects.Types;
using OpenTK;
using OpenTK.Graphics;
@ -141,7 +142,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
public void UpdateProgress(double completionProgress)
{
Position = slider.StackedPositionAt(completionProgress);
Position = slider.CurvePositionAt(completionProgress);
}
}
}

View File

@ -29,6 +29,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
set { path.PathWidth = value; }
}
/// <summary>
/// Offset in absolute coordinates from the start of the curve.
/// </summary>
public Vector2 PathOffset { get; private set; }
public readonly List<Vector2> CurrentCurve = new List<Vector2>();
public readonly Bindable<bool> SnakingIn = new Bindable<bool>();
public readonly Bindable<bool> SnakingOut = new Bindable<bool>();
@ -75,6 +82,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
private int textureWidth => (int)PathWidth * 2;
private Vector2 topLeftOffset;
private readonly Slider slider;
public SliderBody(Slider s)
{
@ -84,6 +93,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
container = new BufferedContainer
{
RelativeSizeAxes = Axes.Both,
CacheDrawnFrameBuffer = true,
Children = new Drawable[]
{
@ -107,11 +117,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
if (updateSnaking(p0, p1))
{
// Autosizing does not give us the desired behaviour here.
// We want the container to have the same size as the slider,
// and to be positioned such that the slider head is at (0,0).
container.Size = path.Size;
container.Position = -path.PositionInBoundingBox(slider.Curve.PositionAt(0) - CurrentCurve[0]);
// The path is generated such that its size encloses it. This change of size causes the path
// to move around while snaking, so we need to offset it to make sure it maintains the
// same position as when it is fully snaked.
var newTopLeftOffset = path.PositionInBoundingBox(Vector2.Zero);
path.Position = topLeftOffset - newTopLeftOffset;
container.ForceRedraw();
}
@ -121,6 +131,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
private void load()
{
reloadTexture();
computeSize();
}
private void reloadTexture()
@ -164,7 +175,19 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
path.Texture = texture;
}
public readonly List<Vector2> CurrentCurve = new List<Vector2>();
private void computeSize()
{
// Generate the entire curve
slider.Curve.GetPathToProgress(CurrentCurve, 0, 1);
foreach (Vector2 p in CurrentCurve)
path.AddVertex(p);
Size = path.Size;
topLeftOffset = path.PositionInBoundingBox(Vector2.Zero);
PathOffset = path.PositionInBoundingBox(CurrentCurve[0]);
}
private bool updateSnaking(double p0, double p1)
{
if (SnakedStart == p0 && SnakedEnd == p1) return false;
@ -176,7 +199,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
path.ClearVertices();
foreach (Vector2 p in CurrentCurve)
path.AddVertex(p - CurrentCurve[0]);
path.AddVertex(p);
return true;
}

View File

@ -23,8 +23,8 @@ namespace osu.Game.Rulesets.Osu.Objects
public double EndTime => StartTime + this.SpanCount() * Curve.Distance / Velocity;
public double Duration => EndTime - StartTime;
public Vector2 StackedPositionAt(double t) => this.PositionAt(t) + StackOffset;
public override Vector2 EndPosition => this.PositionAt(1);
public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t);
public override Vector2 EndPosition => Position + this.CurvePositionAt(1);
public SliderCurve Curve { get; } = new SliderCurve();
@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Objects
HeadCircle = new HitCircle
{
StartTime = StartTime,
Position = StackedPosition,
Position = Position,
IndexInCurrentCombo = IndexInCurrentCombo,
ComboColour = ComboColour,
Samples = Samples,
@ -109,7 +109,7 @@ namespace osu.Game.Rulesets.Osu.Objects
TailCircle = new HitCircle
{
StartTime = EndTime,
Position = StackedEndPosition,
Position = EndPosition,
IndexInCurrentCombo = IndexInCurrentCombo,
ComboColour = ComboColour
};
@ -156,7 +156,7 @@ namespace osu.Game.Rulesets.Osu.Objects
SpanIndex = span,
SpanStartTime = spanStartTime,
StartTime = spanStartTime + timeProgress * SpanDuration,
Position = Curve.PositionAt(distanceProgress),
Position = Position + Curve.PositionAt(distanceProgress),
StackHeight = StackHeight,
Scale = Scale,
ComboColour = ComboColour,
@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Osu.Objects
RepeatIndex = repeatIndex,
SpanDuration = SpanDuration,
StartTime = StartTime + repeat * SpanDuration,
Position = Curve.PositionAt(repeat % 2),
Position = Position + Curve.PositionAt(repeat % 2),
StackHeight = StackHeight,
Scale = Scale,
ComboColour = ComboColour,

View File

@ -118,8 +118,8 @@ namespace osu.Game.Rulesets.Osu.Tests
ComboColour = Color4.LightSeaGreen,
ControlPoints = new List<Vector2>
{
new Vector2(-(distance / 2), 0),
new Vector2(distance / 2, 0),
Vector2.Zero,
new Vector2(distance, 0),
},
Distance = distance,
RepeatCount = repeats,
@ -139,9 +139,9 @@ namespace osu.Game.Rulesets.Osu.Tests
ComboColour = Color4.LightSeaGreen,
ControlPoints = new List<Vector2>
{
new Vector2(-200, 0),
new Vector2(0, 200),
new Vector2(200, 0)
Vector2.Zero,
new Vector2(200, 200),
new Vector2(400, 0)
},
Distance = 600,
RepeatCount = repeats,
@ -163,12 +163,12 @@ namespace osu.Game.Rulesets.Osu.Tests
ComboColour = Color4.LightSeaGreen,
ControlPoints = new List<Vector2>
{
new Vector2(-200, 0),
new Vector2(-50, 75),
new Vector2(0, 100),
new Vector2(100, -200),
Vector2.Zero,
new Vector2(150, 75),
new Vector2(200, 0),
new Vector2(230, 0)
new Vector2(300, -200),
new Vector2(400, 0),
new Vector2(430, 0)
},
Distance = 793.4417,
RepeatCount = repeats,
@ -190,11 +190,11 @@ namespace osu.Game.Rulesets.Osu.Tests
ComboColour = Color4.LightSeaGreen,
ControlPoints = new List<Vector2>
{
new Vector2(-200, 0),
new Vector2(-50, 75),
new Vector2(0, 100),
new Vector2(100, -200),
new Vector2(230, 0)
Vector2.Zero,
new Vector2(150, 75),
new Vector2(200, 100),
new Vector2(300, -200),
new Vector2(430, 0)
},
Distance = 480,
RepeatCount = repeats,
@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Osu.Tests
ComboColour = Color4.LightSeaGreen,
ControlPoints = new List<Vector2>
{
new Vector2(0, 0),
Vector2.Zero,
new Vector2(-200, 0),
new Vector2(0, 0),
new Vector2(0, -200),
@ -247,10 +247,10 @@ namespace osu.Game.Rulesets.Osu.Tests
CurveType = CurveType.Catmull,
ControlPoints = new List<Vector2>
{
new Vector2(-100, 0),
new Vector2(-50, -50),
new Vector2(50, 50),
new Vector2(100, 0)
Vector2.Zero,
new Vector2(50, -50),
new Vector2(150, 50),
new Vector2(200, 0)
},
Distance = 300,
RepeatCount = repeats,

View File

@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Taiko.Replays
{
foreach (var tick in drumRoll.NestedHitObjects.OfType<DrumRollTick>())
{
Frames.Add(new TaikoReplayFrame(tick.StartTime, hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2));
Frames.Add(new TaikoReplayFrame(tick.StartTime, hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2));
hitButton = !hitButton;
}
}
@ -95,16 +95,16 @@ namespace osu.Game.Rulesets.Taiko.Replays
if (hit is CentreHit)
{
if (h.IsStrong)
button = ReplayButtonState.Right1 | ReplayButtonState.Right2;
button = ReplayButtonState.Left1 | ReplayButtonState.Left2;
else
button = hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2;
button = hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2;
}
else
{
if (h.IsStrong)
button = ReplayButtonState.Left1 | ReplayButtonState.Left2;
button = ReplayButtonState.Right1 | ReplayButtonState.Right2;
else
button = hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2;
button = hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2;
}
Frames.Add(new TaikoReplayFrame(h.StartTime, button));

View File

@ -19,13 +19,13 @@ namespace osu.Game.Rulesets.Taiko.Replays
var actions = new List<TaikoAction>();
if (CurrentFrame?.MouseRight1 == true)
actions.Add(TaikoAction.LeftCentre);
if (CurrentFrame?.MouseRight2 == true)
actions.Add(TaikoAction.RightCentre);
if (CurrentFrame?.MouseLeft1 == true)
actions.Add(TaikoAction.LeftRim);
if (CurrentFrame?.MouseLeft2 == true)
if (CurrentFrame?.MouseRight2 == true)
actions.Add(TaikoAction.RightRim);
if (CurrentFrame?.MouseLeft1 == true)
actions.Add(TaikoAction.LeftCentre);
if (CurrentFrame?.MouseLeft2 == true)
actions.Add(TaikoAction.RightCentre);
return new List<InputState> { new ReplayState<TaikoAction> { PressedActions = actions } };
}

View File

@ -207,6 +207,12 @@ namespace osu.Game.Tests.Visual
checkVisibleItemCount(true, 0);
AddAssert("Selection is null", () => currentSelection == null);
advanceSelection(true);
AddAssert("Selection is null", () => currentSelection == null);
advanceSelection(false);
AddAssert("Selection is null", () => currentSelection == null);
AddStep("Un-filter", () => carousel.Filter(new FilterCriteria(), false));
AddAssert("Selection is non-null", () => currentSelection != null);

View File

@ -35,13 +35,13 @@ namespace osu.Game.Tests.Visual
new HitCircle { Position = new Vector2(344, 148), Scale = 0.5f },
new Slider
{
Position = new Vector2(128, 256),
ControlPoints = new List<Vector2>
{
new Vector2(128, 256),
new Vector2(344, 256),
Vector2.Zero,
new Vector2(216, 0),
},
Distance = 400,
Position = new Vector2(128, 256),
Velocity = 1,
TickDistance = 100,
Scale = 0.5f,

View File

@ -8,12 +8,15 @@ using OpenTK;
using osu.Framework.Allocation;
using osu.Game.Configuration;
using osu.Framework.Configuration;
using osu.Framework.MathUtils;
namespace osu.Game.Graphics.Containers
{
public class ParallaxContainer : Container, IRequireHighFrequencyMousePosition
{
public float ParallaxAmount = 0.02f;
public const float DEFAULT_PARALLAX_AMOUNT = 0.02f;
public float ParallaxAmount = DEFAULT_PARALLAX_AMOUNT;
private Bindable<bool> parallaxEnabled;
@ -61,8 +64,9 @@ namespace osu.Game.Graphics.Containers
if (parallaxEnabled)
{
Vector2 offset = input.CurrentState.Mouse == null ? Vector2.Zero : ToLocalSpace(input.CurrentState.Mouse.NativeState.Position) - DrawSize / 2;
content.MoveTo(offset * ParallaxAmount, firstUpdate ? 0 : 1000, Easing.OutQuint);
Vector2 offset = (input.CurrentState.Mouse == null ? Vector2.Zero : ToLocalSpace(input.CurrentState.Mouse.NativeState.Position) - DrawSize / 2) * ParallaxAmount;
content.Position = Interpolation.ValueAt(Clock.ElapsedFrameTime, content.Position, offset, 0, 1000, Easing.OutQuint);
content.Scale = new Vector2(1 + ParallaxAmount);
}

View File

@ -20,6 +20,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Audio;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Platform;
using osu.Framework.Threading;
@ -420,6 +421,7 @@ namespace osu.Game
sensitivity.Disabled = true;
frameworkConfig.Set(FrameworkSetting.ActiveInputHandlers, string.Empty);
frameworkConfig.GetBindable<ConfineMouseMode>(FrameworkSetting.ConfineMouseMode).SetDefault();
return true;
case GlobalAction.ToggleToolbar:
Toolbar.ToggleVisibility();

View File

@ -65,6 +65,14 @@ namespace osu.Game.Overlays.Mods
Ruleset.TriggerChange();
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
Ruleset.UnbindAll();
SelectedMods.UnbindAll();
}
private void selectedModsChanged(IEnumerable<Mod> obj)
{
foreach (ModSection section in ModSectionsContainer.Children)

View File

@ -41,9 +41,11 @@ namespace osu.Game.Rulesets.Objects.Legacy
}
else if ((type & ConvertHitObjectType.Slider) > 0)
{
var pos = new Vector2(int.Parse(split[0]), int.Parse(split[1]));
CurveType curveType = CurveType.Catmull;
double length = 0;
var points = new List<Vector2> { new Vector2(int.Parse(split[0]), int.Parse(split[1])) };
var points = new List<Vector2> { Vector2.Zero };
string[] pointsplit = split[5].Split('|');
foreach (string t in pointsplit)
@ -69,7 +71,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
}
string[] temp = t.Split(':');
points.Add(new Vector2((int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture), (int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)));
points.Add(new Vector2((int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture), (int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)) - pos);
}
int repeatCount = Convert.ToInt32(split[6], CultureInfo.InvariantCulture);
@ -134,7 +136,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
for (int i = 0; i < nodes; i++)
nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i]));
result = CreateSlider(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, points, length, curveType, repeatCount, nodeSamples);
result = CreateSlider(pos, combo, points, length, curveType, repeatCount, nodeSamples);
}
else if ((type & ConvertHitObjectType.Spinner) > 0)
{

View File

@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Objects.Types
/// <param name="obj">The curve.</param>
/// <param name="progress">[0, 1] where 0 is the start time of the <see cref="HitObject"/> and 1 is the end time of the <see cref="HitObject"/>.</param>
/// <returns>The position on the curve.</returns>
public static Vector2 PositionAt(this IHasCurve obj, double progress)
public static Vector2 CurvePositionAt(this IHasCurve obj, double progress)
=> obj.Curve.PositionAt(obj.ProgressAt(progress));
/// <summary>

View File

@ -52,6 +52,10 @@ namespace osu.Game.Screens
protected readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
protected virtual float BackgroundParallaxAmount => 1;
private ParallaxContainer backgroundParallaxContainer;
public WorkingBeatmap InitialBeatmap
{
set
@ -102,11 +106,10 @@ namespace osu.Game.Screens
protected override void OnResuming(Screen last)
{
base.OnResuming(last);
logo.AppendAnimatingAction(() => LogoArriving(logo, true), true);
sampleExit?.Play();
applyArrivingDefaults(true);
ShowOverlays.Value = ShowOverlaysOnEnter;
base.OnResuming(last);
}
protected override void OnSuspending(Screen next)
@ -123,6 +126,8 @@ namespace osu.Game.Screens
if (lastOsu?.Background != null)
{
backgroundParallaxContainer = lastOsu.backgroundParallaxContainer;
if (bg == null || lastOsu.Background.Equals(bg))
//we can keep the previous mode's background.
Background = lastOsu.Background;
@ -136,7 +141,7 @@ namespace osu.Game.Screens
// this makes up for the fact our padding changes when the global toolbar is visible.
bg.Scale = new Vector2(1.06f);
AddInternal(new ParallaxContainer
AddInternal(backgroundParallaxContainer = new ParallaxContainer
{
Depth = float.MaxValue,
Children = new[]
@ -149,11 +154,9 @@ namespace osu.Game.Screens
if ((logo = lastOsu?.logo) == null)
LoadComponentAsync(logo = new OsuLogo { Alpha = 0 }, AddInternal);
logo.AppendAnimatingAction(() => LogoArriving(logo, false), true);
applyArrivingDefaults(false);
base.OnEntering(last);
ShowOverlays.Value = ShowOverlaysOnEnter;
}
protected override bool OnExiting(Screen next)
@ -193,6 +196,16 @@ namespace osu.Game.Screens
logo.Ripple = true;
}
private void applyArrivingDefaults(bool isResuming)
{
logo.AppendAnimatingAction(() => LogoArriving(logo, isResuming), true);
if (backgroundParallaxContainer != null)
backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount;
ShowOverlays.Value = ShowOverlaysOnEnter;
}
private void onExitingLogo()
{
logo.AppendAnimatingAction(() => { LogoExiting(logo); }, false);

View File

@ -37,6 +37,8 @@ namespace osu.Game.Screens.Play
{
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap);
protected override float BackgroundParallaxAmount => 0.1f;
public override bool ShowOverlaysOnEnter => false;
public Action RestartRequested;
@ -351,7 +353,7 @@ namespace osu.Game.Screens.Play
protected override bool OnExiting(Screen next)
{
if ((!AllowPause || HasFailed || !ValidForResume || pauseContainer?.IsPaused != false || RulesetContainer?.HasReplayLoaded != false) && (!pauseContainer?.IsResuming ?? false))
if ((!AllowPause || HasFailed || !ValidForResume || pauseContainer?.IsPaused != false || RulesetContainer?.HasReplayLoaded != false) && (!pauseContainer?.IsResuming ?? true))
{
// In the case of replays, we may have changed the playback rate.
applyRateFromMods();

View File

@ -109,7 +109,7 @@ namespace osu.Game.Screens.Play
{
var xFill = value * UsableWidth;
fill.Width = xFill;
handleBase.MoveToX(xFill);
handleBase.X = xFill;
}
protected override void OnUserChange() => OnSeek?.Invoke(Current);

View File

@ -192,7 +192,9 @@ namespace osu.Game.Screens.Select
/// <param name="skipDifficulties">Whether to skip individual difficulties and only increment over full groups.</param>
public void SelectNext(int direction = 1, bool skipDifficulties = true)
{
if (!Items.Any())
var visibleItems = Items.Where(s => !s.Item.Filtered).ToList();
if (!visibleItems.Any())
return;
DrawableCarouselItem drawable = null;
@ -202,15 +204,15 @@ namespace osu.Game.Screens.Select
// we can fix this by changing this method to not reference drawables / Items in the first place.
return;
int originalIndex = Items.IndexOf(drawable);
int originalIndex = visibleItems.IndexOf(drawable);
int currentIndex = originalIndex;
// local function to increment the index in the required direction, wrapping over extremities.
int incrementIndex() => currentIndex = (currentIndex + direction + Items.Count) % Items.Count;
int incrementIndex() => currentIndex = (currentIndex + direction + visibleItems.Count) % visibleItems.Count;
while (incrementIndex() != originalIndex)
{
var item = Items[currentIndex].Item;
var item = visibleItems[currentIndex].Item;
if (item.Filtered || item.State == CarouselItemState.Selected) continue;
@ -407,12 +409,14 @@ namespace osu.Game.Screens.Select
continue;
}
float depth = i + (item is DrawableCarouselBeatmapSet ? -Items.Count : 0);
// Only add if we're not already part of the content.
if (!scrollableContent.Contains(item))
{
// Makes sure headers are always _below_ items,
// and depth flows downward.
item.Depth = i + (item is DrawableCarouselBeatmapSet ? -Items.Count : 0);
item.Depth = depth;
switch (item.LoadState)
{
@ -426,6 +430,10 @@ namespace osu.Game.Screens.Select
break;
}
}
else
{
scrollableContent.ChangeChildDepth(item, depth);
}
}
// this is not actually useful right now, but once we have groups may well be.

View File

@ -1,11 +1,13 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
@ -47,13 +49,15 @@ namespace osu.Game.Screens.Select
private SampleChannel sampleConfirm;
[BackgroundDependencyLoader(true)]
private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame game)
{
sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection");
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new List<Mod>());
if (game != null)
modSelect.SelectedMods.BindTo(game.SelectedMods);
[BackgroundDependencyLoader(true)]
private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu)
{
if (osu != null) SelectedMods.BindTo(osu.SelectedMods);
modSelect.SelectedMods.BindTo(SelectedMods);
sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection");
Footer.AddButton(@"mods", colours.Yellow, modSelect, Key.F1, float.MaxValue);
@ -80,7 +84,7 @@ namespace osu.Game.Screens.Select
{
base.UpdateBeatmap(beatmap);
beatmap.Mods.BindTo(modSelect.SelectedMods);
beatmap.Mods.BindTo(SelectedMods);
BeatmapDetails.Beatmap = beatmap;
@ -95,7 +99,7 @@ namespace osu.Game.Screens.Select
if (removeAutoModOnResume)
{
var autoType = Ruleset.Value.CreateInstance().GetAutoplayMod().GetType();
modSelect.SelectedMods.Value = modSelect.SelectedMods.Value.Where(m => m.GetType() != autoType).ToArray();
SelectedMods.Value = SelectedMods.Value.Where(m => m.GetType() != autoType).ToArray();
removeAutoModOnResume = false;
}
@ -125,7 +129,7 @@ namespace osu.Game.Screens.Select
if (Beatmap.Value.Track != null)
Beatmap.Value.Track.Looping = false;
Beatmap.Value.Mods.UnbindBindings();
SelectedMods.UnbindAll();
Beatmap.Value.Mods.Value = new Mod[] { };
return false;

View File

@ -386,6 +386,8 @@ namespace osu.Game.Screens.Select
protected override bool OnExiting(Screen next)
{
FinaliseSelection();
beatmapInfoWedge.State = Visibility.Hidden;
Content.FadeOut(100);

View File

@ -39,7 +39,7 @@ namespace osu.Game.Skinning
if (ch == null && allowFallback)
ch = loadChannel(s, audio.Sample.Get);
return ch;
}).ToArray();
}).Where(c => c != null).ToArray();
}
private SampleChannel loadChannel(SampleInfo info, Func<string, SampleChannel> getSampleFunction)