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

Merge remote-tracking branch 'upstream/master' into conversion-test-mods

This commit is contained in:
Dean Herbert 2019-08-05 09:50:43 +02:00
commit 431834fc2f
24 changed files with 855 additions and 91 deletions

View File

@ -5,7 +5,7 @@
<TargetFrameworks>netcoreapp2.0</TargetFrameworks> <TargetFrameworks>netcoreapp2.0</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Cake" Version="0.30.0" /> <PackageReference Include="Cake" Version="0.34.1" />
<PackageReference Include="Cake.CoreCLR" Version="0.30.0" /> <PackageReference Include="Cake.CoreCLR" Version="0.34.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -28,8 +28,8 @@
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="System.IO.Packaging" Version="4.5.0" /> <PackageReference Include="System.IO.Packaging" Version="4.5.0" />
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.4" /> <PackageReference Include="ppy.squirrel.windows" Version="1.9.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Resources"> <ItemGroup Label="Resources">
<EmbeddedResource Include="lazer.ico" /> <EmbeddedResource Include="lazer.ico" />

View File

@ -21,10 +21,9 @@ namespace osu.Game.Rulesets.Osu.Tests
[TestCase("basic")] [TestCase("basic")]
[TestCase("colinear-perfect-curve")] [TestCase("colinear-perfect-curve")]
[TestCase("slider-ticks")] [TestCase("slider-ticks")]
public void Test(string name) [TestCase("repeat-slider")]
{ [TestCase("uneven-repeat-slider")]
base.Test(name); public void Test(string name) => base.Test(name);
}
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject) protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
{ {

View File

@ -0,0 +1,222 @@
{
"Mappings": [{
"StartTime": 369,
"Objects": [{
"StartTime": 369,
"EndTime": 369,
"X": 177,
"Y": 191
},
{
"StartTime": 450,
"EndTime": 450,
"X": 216.539276,
"Y": 191.192871
},
{
"StartTime": 532,
"EndTime": 532,
"X": 256.5667,
"Y": 191.388138
},
{
"StartTime": 614,
"EndTime": 614,
"X": 296.594116,
"Y": 191.583389
},
{
"StartTime": 696,
"EndTime": 696,
"X": 336.621521,
"Y": 191.778641
},
{
"StartTime": 778,
"EndTime": 778,
"X": 376.648926,
"Y": 191.9739
},
{
"StartTime": 860,
"EndTime": 860,
"X": 337.318878,
"Y": 191.782043
},
{
"StartTime": 942,
"EndTime": 942,
"X": 297.291443,
"Y": 191.586792
},
{
"StartTime": 1024,
"EndTime": 1024,
"X": 257.264038,
"Y": 191.391541
},
{
"StartTime": 1106,
"EndTime": 1106,
"X": 217.2366,
"Y": 191.196274
},
{
"StartTime": 1188,
"EndTime": 1188,
"X": 177.209213,
"Y": 191.001022
},
{
"StartTime": 1270,
"EndTime": 1270,
"X": 216.818192,
"Y": 191.194229
},
{
"StartTime": 1352,
"EndTime": 1352,
"X": 256.8456,
"Y": 191.3895
},
{
"StartTime": 1434,
"EndTime": 1434,
"X": 296.873047,
"Y": 191.584747
},
{
"StartTime": 1516,
"EndTime": 1516,
"X": 336.900452,
"Y": 191.78
},
{
"StartTime": 1598,
"EndTime": 1598,
"X": 376.927917,
"Y": 191.975266
},
{
"StartTime": 1680,
"EndTime": 1680,
"X": 337.039948,
"Y": 191.780685
},
{
"StartTime": 1762,
"EndTime": 1762,
"X": 297.0125,
"Y": 191.585434
},
{
"StartTime": 1844,
"EndTime": 1844,
"X": 256.9851,
"Y": 191.390167
},
{
"StartTime": 1926,
"EndTime": 1926,
"X": 216.957672,
"Y": 191.194916
},
{
"StartTime": 2008,
"EndTime": 2008,
"X": 177.069717,
"Y": 191.000336
},
{
"StartTime": 2090,
"EndTime": 2090,
"X": 217.097137,
"Y": 191.1956
},
{
"StartTime": 2172,
"EndTime": 2172,
"X": 257.124573,
"Y": 191.390854
},
{
"StartTime": 2254,
"EndTime": 2254,
"X": 297.152,
"Y": 191.5861
},
{
"StartTime": 2336,
"EndTime": 2336,
"X": 337.179443,
"Y": 191.781372
},
{
"StartTime": 2418,
"EndTime": 2418,
"X": 376.7884,
"Y": 191.974579
},
{
"StartTime": 2500,
"EndTime": 2500,
"X": 336.760956,
"Y": 191.779327
},
{
"StartTime": 2582,
"EndTime": 2582,
"X": 296.733643,
"Y": 191.584076
},
{
"StartTime": 2664,
"EndTime": 2664,
"X": 256.7062,
"Y": 191.388809
},
{
"StartTime": 2746,
"EndTime": 2746,
"X": 216.678772,
"Y": 191.193558
},
{
"StartTime": 2828,
"EndTime": 2828,
"X": 177.348663,
"Y": 191.0017
},
{
"StartTime": 2909,
"EndTime": 2909,
"X": 216.887909,
"Y": 191.19458
},
{
"StartTime": 2991,
"EndTime": 2991,
"X": 256.915344,
"Y": 191.389832
},
{
"StartTime": 3073,
"EndTime": 3073,
"X": 296.942749,
"Y": 191.585083
},
{
"StartTime": 3155,
"EndTime": 3155,
"X": 336.970184,
"Y": 191.78035
},
{
"StartTime": 3201,
"EndTime": 3201,
"X": 376.99762,
"Y": 191.9756
}
]
}]
}

View File

@ -0,0 +1,18 @@
osu file format v14
[General]
StackLeniency: 0.4
Mode: 0
[Difficulty]
CircleSize:4
OverallDifficulty:7
ApproachRate:8
SliderMultiplier:1.6
SliderTickRate:4
[TimingPoints]
369,327.868852459016,4,2,2,32,1,0
[HitObjects]
177,191,369,6,0,L|382:192,7,200

View File

@ -0,0 +1,348 @@
{
"Mappings": [{
"StartTime": 369,
"Objects": [{
"StartTime": 369,
"EndTime": 369,
"X": 127,
"Y": 194
},
{
"StartTime": 450,
"EndTime": 450,
"X": 166.53389,
"Y": 193.8691
},
{
"StartTime": 532,
"EndTime": 532,
"X": 206.555847,
"Y": 193.736572
},
{
"StartTime": 614,
"EndTime": 614,
"X": 246.57782,
"Y": 193.60405
},
{
"StartTime": 696,
"EndTime": 696,
"X": 286.5998,
"Y": 193.471527
},
{
"StartTime": 778,
"EndTime": 778,
"X": 326.621765,
"Y": 193.339
},
{
"StartTime": 860,
"EndTime": 860,
"X": 366.6437,
"Y": 193.206482
},
{
"StartTime": 942,
"EndTime": 942,
"X": 406.66568,
"Y": 193.073959
},
{
"StartTime": 970,
"EndTime": 970,
"X": 420.331726,
"Y": 193.0287
},
{
"StartTime": 997,
"EndTime": 997,
"X": 407.153748,
"Y": 193.072342
},
{
"StartTime": 1079,
"EndTime": 1079,
"X": 367.131775,
"Y": 193.204865
},
{
"StartTime": 1161,
"EndTime": 1161,
"X": 327.1098,
"Y": 193.337387
},
{
"StartTime": 1243,
"EndTime": 1243,
"X": 287.08783,
"Y": 193.46991
},
{
"StartTime": 1325,
"EndTime": 1325,
"X": 247.0659,
"Y": 193.602432
},
{
"StartTime": 1407,
"EndTime": 1407,
"X": 207.043915,
"Y": 193.734955
},
{
"StartTime": 1489,
"EndTime": 1489,
"X": 167.021988,
"Y": 193.867477
},
{
"StartTime": 1571,
"EndTime": 1571,
"X": 127,
"Y": 194
},
{
"StartTime": 1653,
"EndTime": 1653,
"X": 167.021988,
"Y": 193.867477
},
{
"StartTime": 1735,
"EndTime": 1735,
"X": 207.043976,
"Y": 193.734955
},
{
"StartTime": 1817,
"EndTime": 1817,
"X": 247.065887,
"Y": 193.602432
},
{
"StartTime": 1899,
"EndTime": 1899,
"X": 287.08783,
"Y": 193.46991
},
{
"StartTime": 1981,
"EndTime": 1981,
"X": 327.1098,
"Y": 193.337387
},
{
"StartTime": 2062,
"EndTime": 2062,
"X": 366.643738,
"Y": 193.206482
},
{
"StartTime": 2144,
"EndTime": 2144,
"X": 406.665649,
"Y": 193.073959
},
{
"StartTime": 2172,
"EndTime": 2172,
"X": 420.331726,
"Y": 193.0287
},
{
"StartTime": 2199,
"EndTime": 2199,
"X": 407.153748,
"Y": 193.072342
},
{
"StartTime": 2281,
"EndTime": 2281,
"X": 367.1318,
"Y": 193.204865
},
{
"StartTime": 2363,
"EndTime": 2363,
"X": 327.1098,
"Y": 193.337387
},
{
"StartTime": 2445,
"EndTime": 2445,
"X": 287.08783,
"Y": 193.46991
},
{
"StartTime": 2527,
"EndTime": 2527,
"X": 247.065887,
"Y": 193.602432
},
{
"StartTime": 2609,
"EndTime": 2609,
"X": 207.043976,
"Y": 193.734955
},
{
"StartTime": 2691,
"EndTime": 2691,
"X": 167.021988,
"Y": 193.867477
},
{
"StartTime": 2773,
"EndTime": 2773,
"X": 127,
"Y": 194
},
{
"StartTime": 2855,
"EndTime": 2855,
"X": 167.021988,
"Y": 193.867477
},
{
"StartTime": 2937,
"EndTime": 2937,
"X": 207.043976,
"Y": 193.734955
},
{
"StartTime": 3019,
"EndTime": 3019,
"X": 247.065948,
"Y": 193.602432
},
{
"StartTime": 3101,
"EndTime": 3101,
"X": 287.087952,
"Y": 193.46991
},
{
"StartTime": 3183,
"EndTime": 3183,
"X": 327.109772,
"Y": 193.337387
},
{
"StartTime": 3265,
"EndTime": 3265,
"X": 367.131775,
"Y": 193.204865
},
{
"StartTime": 3347,
"EndTime": 3347,
"X": 407.153748,
"Y": 193.072342
},
{
"StartTime": 3374,
"EndTime": 3374,
"X": 420.331726,
"Y": 193.0287
},
{
"StartTime": 3401,
"EndTime": 3401,
"X": 407.153748,
"Y": 193.072342
},
{
"StartTime": 3483,
"EndTime": 3483,
"X": 367.131775,
"Y": 193.204865
},
{
"StartTime": 3565,
"EndTime": 3565,
"X": 327.109772,
"Y": 193.337387
},
{
"StartTime": 3647,
"EndTime": 3647,
"X": 287.087952,
"Y": 193.46991
},
{
"StartTime": 3729,
"EndTime": 3729,
"X": 247.065948,
"Y": 193.602432
},
{
"StartTime": 3811,
"EndTime": 3811,
"X": 207.043976,
"Y": 193.734955
},
{
"StartTime": 3893,
"EndTime": 3893,
"X": 167.021988,
"Y": 193.867477
},
{
"StartTime": 3975,
"EndTime": 3975,
"X": 127,
"Y": 194
},
{
"StartTime": 4057,
"EndTime": 4057,
"X": 167.021988,
"Y": 193.867477
},
{
"StartTime": 4139,
"EndTime": 4139,
"X": 207.043976,
"Y": 193.734955
},
{
"StartTime": 4221,
"EndTime": 4221,
"X": 247.065948,
"Y": 193.602432
},
{
"StartTime": 4303,
"EndTime": 4303,
"X": 287.087952,
"Y": 193.46991
},
{
"StartTime": 4385,
"EndTime": 4385,
"X": 327.109772,
"Y": 193.337387
},
{
"StartTime": 4467,
"EndTime": 4467,
"X": 367.131775,
"Y": 193.204865
},
{
"StartTime": 4540,
"EndTime": 4540,
"X": 420.331726,
"Y": 193.0287
},
{
"StartTime": 4549,
"EndTime": 4549,
"X": 407.153748,
"Y": 193.072342
}
]
}]
}

View File

@ -0,0 +1,19 @@
osu file format v14
[General]
StackLeniency: 0.4
Mode: 0
[Difficulty]
CircleSize:4
OverallDifficulty:7
ApproachRate:8
SliderMultiplier:1.6
SliderTickRate:4
[TimingPoints]
369,327.868852459016,4,2,2,32,1,0
[HitObjects]
// A slider with an un-even amount of ticks
127,194,369,6,0,L|429:193,7,293.333333333333

View File

@ -0,0 +1,116 @@
// 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 NUnit.Framework;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Tests.Beatmaps
{
[TestFixture]
public class SliderEventGenerationTest
{
private const double start_time = 0;
private const double span_duration = 1000;
[Test]
public void TestSingleSpan()
{
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, null).ToArray();
Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head));
Assert.That(events[0].Time, Is.EqualTo(start_time));
Assert.That(events[1].Type, Is.EqualTo(SliderEventType.Tick));
Assert.That(events[1].Time, Is.EqualTo(span_duration / 2));
Assert.That(events[3].Type, Is.EqualTo(SliderEventType.Tail));
Assert.That(events[3].Time, Is.EqualTo(span_duration));
}
[Test]
public void TestRepeat()
{
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 2, null).ToArray();
Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head));
Assert.That(events[0].Time, Is.EqualTo(start_time));
Assert.That(events[1].Type, Is.EqualTo(SliderEventType.Tick));
Assert.That(events[1].Time, Is.EqualTo(span_duration / 2));
Assert.That(events[2].Type, Is.EqualTo(SliderEventType.Repeat));
Assert.That(events[2].Time, Is.EqualTo(span_duration));
Assert.That(events[3].Type, Is.EqualTo(SliderEventType.Tick));
Assert.That(events[3].Time, Is.EqualTo(span_duration + span_duration / 2));
Assert.That(events[5].Type, Is.EqualTo(SliderEventType.Tail));
Assert.That(events[5].Time, Is.EqualTo(2 * span_duration));
}
[Test]
public void TestNonEvenTicks()
{
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, 300, span_duration, 2, null).ToArray();
Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head));
Assert.That(events[0].Time, Is.EqualTo(start_time));
Assert.That(events[1].Type, Is.EqualTo(SliderEventType.Tick));
Assert.That(events[1].Time, Is.EqualTo(300));
Assert.That(events[2].Type, Is.EqualTo(SliderEventType.Tick));
Assert.That(events[2].Time, Is.EqualTo(600));
Assert.That(events[3].Type, Is.EqualTo(SliderEventType.Tick));
Assert.That(events[3].Time, Is.EqualTo(900));
Assert.That(events[4].Type, Is.EqualTo(SliderEventType.Repeat));
Assert.That(events[4].Time, Is.EqualTo(span_duration));
Assert.That(events[5].Type, Is.EqualTo(SliderEventType.Tick));
Assert.That(events[5].Time, Is.EqualTo(1100));
Assert.That(events[6].Type, Is.EqualTo(SliderEventType.Tick));
Assert.That(events[6].Time, Is.EqualTo(1400));
Assert.That(events[7].Type, Is.EqualTo(SliderEventType.Tick));
Assert.That(events[7].Time, Is.EqualTo(1700));
Assert.That(events[9].Type, Is.EqualTo(SliderEventType.Tail));
Assert.That(events[9].Time, Is.EqualTo(2 * span_duration));
}
[Test]
public void TestLegacyLastTickOffset()
{
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, 100).ToArray();
Assert.That(events[2].Type, Is.EqualTo(SliderEventType.LegacyLastTick));
Assert.That(events[2].Time, Is.EqualTo(900));
}
[Test]
public void TestMinimumTickDistance()
{
const double velocity = 5;
const double min_distance = velocity * 10;
var events = SliderEventGenerator.Generate(start_time, span_duration, velocity, velocity, span_duration, 2, 0).ToArray();
Assert.Multiple(() =>
{
int tickIndex = -1;
while (++tickIndex < events.Length)
{
if (events[tickIndex].Type != SliderEventType.Tick)
continue;
Assert.That(events[tickIndex].Time, Is.LessThan(span_duration - min_distance).Or.GreaterThan(span_duration + min_distance));
}
});
}
}
}

View File

@ -9,6 +9,8 @@ using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Taiko; using osu.Game.Rulesets.Taiko;
using osu.Game.Users;
using osu.Framework.Bindables;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
{ {
@ -23,18 +25,25 @@ namespace osu.Game.Tests.Visual.Online
public TestSceneProfileRulesetSelector() public TestSceneProfileRulesetSelector()
{ {
ProfileRulesetSelector selector; ProfileRulesetSelector selector;
Bindable<User> user = new Bindable<User>();
Child = selector = new ProfileRulesetSelector Child = selector = new ProfileRulesetSelector
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
User = { BindTarget = user }
}; };
AddStep("set osu! as default", () => selector.SetDefaultRuleset(new OsuRuleset().RulesetInfo)); AddStep("set osu! as default", () => selector.SetDefaultRuleset(new OsuRuleset().RulesetInfo));
AddStep("set mania as default", () => selector.SetDefaultRuleset(new ManiaRuleset().RulesetInfo)); AddStep("set mania as default", () => selector.SetDefaultRuleset(new ManiaRuleset().RulesetInfo));
AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo)); AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo));
AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo)); AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo));
AddStep("select default ruleset", selector.SelectDefaultRuleset);
AddStep("User with osu as default", () => user.Value = new User { PlayMode = "osu" });
AddStep("User with mania as default", () => user.Value = new User { PlayMode = "mania" });
AddStep("User with taiko as default", () => user.Value = new User { PlayMode = "taiko" });
AddStep("User with catch as default", () => user.Value = new User { PlayMode = "fruits" });
AddStep("null user", () => user.Value = null);
} }
} }
} }

View File

@ -150,7 +150,7 @@ namespace osu.Game.Beatmaps
processor?.PostProcess(); processor?.PostProcess();
foreach (var mod in mods.OfType<IApplicableToBeatmap>()) foreach (var mod in mods.OfType<IApplicableToBeatmap>())
mod.ApplyToBeatmap(Beatmap); mod.ApplyToBeatmap(converted);
return converted; return converted;
} }

View File

@ -92,7 +92,8 @@ namespace osu.Game.Graphics
using (var image = await host.TakeScreenshotAsync()) using (var image = await host.TakeScreenshotAsync())
{ {
Interlocked.Decrement(ref screenShotTasks); if (Interlocked.Decrement(ref screenShotTasks) == 0 && cursorVisibility.Value == false)
cursorVisibility.Value = true;
var fileName = getFileName(); var fileName = getFileName();
if (fileName == null) return; if (fileName == null) return;
@ -125,14 +126,6 @@ namespace osu.Game.Graphics
} }
}); });
protected override void Update()
{
base.Update();
if (cursorVisibility.Value == false && Interlocked.CompareExchange(ref screenShotTasks, 0, 0) == 0)
cursorVisibility.Value = true;
}
private string getFileName() private string getFileName()
{ {
var dt = DateTime.Now; var dt = DateTime.Now;

View File

@ -0,0 +1,44 @@
// 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 osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Extensions.Color4Extensions;
namespace osu.Game.Graphics.UserInterface
{
public class DimmedLoadingLayer : VisibilityContainer
{
private const float transition_duration = 250;
private readonly LoadingAnimation loading;
public DimmedLoadingLayer()
{
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
},
loading = new LoadingAnimation(),
};
}
protected override void PopIn()
{
this.FadeIn(transition_duration, Easing.OutQuint);
loading.Show();
}
protected override void PopOut()
{
this.FadeOut(transition_duration, Easing.OutQuint);
loading.Hide();
}
}
}

View File

@ -81,7 +81,8 @@ namespace osu.Game.Graphics.UserInterface
Colour = Color4.White, Colour = Color4.White,
Origin = Anchor.BottomLeft, Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft, Anchor = Anchor.BottomLeft,
} },
new HoverClickSounds()
}; };
Current.ValueChanged += selected => Current.ValueChanged += selected =>

View File

@ -27,6 +27,7 @@ namespace osu.Game.Online.API.Requests
{ {
Favourite, Favourite,
RankedAndApproved, RankedAndApproved,
Loved,
Unranked, Unranked,
Graveyard Graveyard
} }

View File

@ -307,7 +307,9 @@ namespace osu.Game
if (nextBeatmap?.Track != null) if (nextBeatmap?.Track != null)
nextBeatmap.Track.Completed += currentTrackCompleted; nextBeatmap.Track.Completed += currentTrackCompleted;
beatmap.OldValue?.Dispose(); using (var oldBeatmap = beatmap.OldValue)
if (oldBeatmap?.Track != null)
oldBeatmap.Track.Completed -= currentTrackCompleted;
nextBeatmap?.LoadBeatmapAsync(); nextBeatmap?.LoadBeatmapAsync();
} }

View File

@ -2,11 +2,13 @@
// 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 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.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Users;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -16,6 +18,8 @@ namespace osu.Game.Overlays.Profile.Header.Components
{ {
private Color4 accentColour = Color4.White; private Color4 accentColour = Color4.White;
public readonly Bindable<User> User = new Bindable<User>();
public ProfileRulesetSelector() public ProfileRulesetSelector()
{ {
TabContainer.Masking = false; TabContainer.Masking = false;
@ -32,24 +36,17 @@ namespace osu.Game.Overlays.Profile.Header.Components
((ProfileRulesetTabItem)tabItem).AccentColour = accentColour; ((ProfileRulesetTabItem)tabItem).AccentColour = accentColour;
} }
public void SetDefaultRuleset(RulesetInfo ruleset) protected override void LoadComplete()
{ {
// Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value base.LoadComplete();
foreach (TabItem<RulesetInfo> tabItem in TabContainer)
((ProfileRulesetTabItem)tabItem).IsDefault = ((ProfileRulesetTabItem)tabItem).Value.ID == ruleset.ID; User.BindValueChanged(u => SetDefaultRuleset(Rulesets.GetRuleset(u.NewValue?.PlayMode ?? "osu")), true);
} }
public void SelectDefaultRuleset() public void SetDefaultRuleset(RulesetInfo ruleset)
{ {
// Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value
foreach (TabItem<RulesetInfo> tabItem in TabContainer) foreach (TabItem<RulesetInfo> tabItem in TabContainer)
{ ((ProfileRulesetTabItem)tabItem).IsDefault = ((ProfileRulesetTabItem)tabItem).Value.ID == ruleset.ID;
if (((ProfileRulesetTabItem)tabItem).IsDefault)
{
Current.Value = ((ProfileRulesetTabItem)tabItem).Value;
return;
}
}
} }
protected override TabItem<RulesetInfo> CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value) protected override TabItem<RulesetInfo> CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value)

View File

@ -80,7 +80,6 @@ namespace osu.Game.Overlays.Profile.Header.Components
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
background.Colour = colours.Pink; background.Colour = colours.Pink;
iconContainer.Colour = colours.GreySeafoam;
} }
} }
} }

View File

@ -18,6 +18,7 @@ namespace osu.Game.Overlays.Profile.Sections
{ {
new PaginatedBeatmapContainer(BeatmapSetType.Favourite, User, "Favourite Beatmaps"), new PaginatedBeatmapContainer(BeatmapSetType.Favourite, User, "Favourite Beatmaps"),
new PaginatedBeatmapContainer(BeatmapSetType.RankedAndApproved, User, "Ranked & Approved Beatmaps"), new PaginatedBeatmapContainer(BeatmapSetType.RankedAndApproved, User, "Ranked & Approved Beatmaps"),
new PaginatedBeatmapContainer(BeatmapSetType.Loved, User, "Loved Beatmaps"),
new PaginatedBeatmapContainer(BeatmapSetType.Unranked, User, "Pending Beatmaps"), new PaginatedBeatmapContainer(BeatmapSetType.Unranked, User, "Pending Beatmaps"),
new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, "Graveyarded Beatmaps"), new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, "Graveyarded Beatmaps"),
}; };

View File

@ -84,6 +84,7 @@ namespace osu.Game.Overlays.Settings
Content.Anchor = Anchor.CentreLeft; Content.Anchor = Anchor.CentreLeft;
Content.Origin = Anchor.CentreLeft; Content.Origin = Anchor.CentreLeft;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
ScrollbarVisible = false;
} }
} }

View File

@ -186,7 +186,7 @@ namespace osu.Game.Overlays
base.UpdateAfterChildren(); base.UpdateAfterChildren();
ContentContainer.Margin = new MarginPadding { Left = Sidebar?.DrawWidth ?? 0 }; ContentContainer.Margin = new MarginPadding { Left = Sidebar?.DrawWidth ?? 0 };
ContentContainer.Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 }; Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 };
} }
protected class SettingsSectionsContainer : SectionsContainer<SettingsSection> protected class SettingsSectionsContainer : SectionsContainer<SettingsSection>

View File

@ -3,13 +3,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using osuTK; using osuTK;
namespace osu.Game.Rulesets.Objects namespace osu.Game.Rulesets.Objects
{ {
public static class SliderEventGenerator public static class SliderEventGenerator
{ {
public static IEnumerable<SliderEventDescriptor> Generate(double startTime, double spanDuration, double velocity, double tickDistance, double totalDistance, int spanCount, double? legacyLastTickOffset) public static IEnumerable<SliderEventDescriptor> Generate(double startTime, double spanDuration, double velocity, double tickDistance, double totalDistance, int spanCount,
double? legacyLastTickOffset)
{ {
// A very lenient maximum length of a slider for ticks to be generated. // A very lenient maximum length of a slider for ticks to be generated.
// This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage. // This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage.
@ -36,24 +38,17 @@ namespace osu.Game.Rulesets.Objects
var spanStartTime = startTime + span * spanDuration; var spanStartTime = startTime + span * spanDuration;
var reversed = span % 2 == 1; var reversed = span % 2 == 1;
for (var d = tickDistance; d <= length; d += tickDistance) var ticks = generateTicks(span, spanStartTime, spanDuration, reversed, length, tickDistance, minDistanceFromEnd);
if (reversed)
{ {
if (d >= length - minDistanceFromEnd) // For repeat spans, ticks are returned in reverse-StartTime order, which is undesirable for some rulesets
break; ticks = ticks.Reverse();
var pathProgress = d / length;
var timeProgress = reversed ? 1 - pathProgress : pathProgress;
yield return new SliderEventDescriptor
{
Type = SliderEventType.Tick,
SpanIndex = span,
SpanStartTime = spanStartTime,
Time = spanStartTime + timeProgress * spanDuration,
PathProgress = pathProgress,
};
} }
foreach (var e in ticks)
yield return e;
if (span < spanCount - 1) if (span < spanCount - 1)
{ {
yield return new SliderEventDescriptor yield return new SliderEventDescriptor
@ -103,6 +98,40 @@ namespace osu.Game.Rulesets.Objects
PathProgress = spanCount % 2, PathProgress = spanCount % 2,
}; };
} }
/// <summary>
/// Generates the ticks for a span of the slider.
/// </summary>
/// <param name="spanIndex">The span index.</param>
/// <param name="spanStartTime">The start time of the span.</param>
/// <param name="spanDuration">The duration of the span.</param>
/// <param name="reversed">Whether the span is reversed.</param>
/// <param name="length">The length of the path.</param>
/// <param name="tickDistance">The distance between each tick.</param>
/// <param name="minDistanceFromEnd">The distance from the end of the path at which ticks are not allowed to be added.</param>
/// <returns>A <see cref="SliderEventDescriptor"/> for each tick. If <paramref name="reversed"/> is true, the ticks will be returned in reverse-StartTime order.</returns>
private static IEnumerable<SliderEventDescriptor> generateTicks(int spanIndex, double spanStartTime, double spanDuration, bool reversed, double length, double tickDistance,
double minDistanceFromEnd)
{
for (var d = tickDistance; d <= length; d += tickDistance)
{
if (d >= length - minDistanceFromEnd)
break;
// Always generate ticks from the start of the path rather than the span to ensure that ticks in repeat spans are positioned identically to those in non-repeat spans
var pathProgress = d / length;
var timeProgress = reversed ? 1 - pathProgress : pathProgress;
yield return new SliderEventDescriptor
{
Type = SliderEventType.Tick,
SpanIndex = spanIndex,
SpanStartTime = spanStartTime,
Time = spanStartTime + timeProgress * spanDuration,
PathProgress = pathProgress,
};
}
}
} }
/// <summary> /// <summary>

View File

@ -35,7 +35,7 @@ namespace osu.Game.Screens.Select
private readonly MetadataSection description, source, tags; private readonly MetadataSection description, source, tags;
private readonly Container failRetryContainer; private readonly Container failRetryContainer;
private readonly FailRetryGraph failRetryGraph; private readonly FailRetryGraph failRetryGraph;
private readonly DimmedLoadingAnimation loading; private readonly DimmedLoadingLayer loading;
private IAPIProvider api; private IAPIProvider api;
@ -156,10 +156,7 @@ namespace osu.Game.Screens.Select
}, },
}, },
}, },
loading = new DimmedLoadingAnimation loading = new DimmedLoadingLayer(),
{
RelativeSizeAxes = Axes.Both,
},
}; };
} }
@ -365,35 +362,5 @@ namespace osu.Game.Screens.Select
}); });
} }
} }
private class DimmedLoadingAnimation : VisibilityContainer
{
private readonly LoadingAnimation loading;
public DimmedLoadingAnimation()
{
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
},
loading = new LoadingAnimation(),
};
}
protected override void PopIn()
{
this.FadeIn(transition_duration, Easing.OutQuint);
loading.Show();
}
protected override void PopOut()
{
this.FadeOut(transition_duration, Easing.OutQuint);
loading.Hide();
}
}
} }
} }

View File

@ -11,8 +11,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Humanizer" Version="2.6.2" /> <PackageReference Include="Humanizer" Version="2.6.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.702.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.730.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.730.0" />

View File

@ -14,8 +14,6 @@
<string>0.1.0</string> <string>0.1.0</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>10.0</string> <string>10.0</string>
<key>UIDeviceFamily</key> <key>UIDeviceFamily</key>