mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 23:12:56 +08:00
Merge branch 'master' into adjustable-rate-mods
This commit is contained in:
commit
9961fa7385
@ -54,6 +54,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.1210.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.1212.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -2,23 +2,21 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Scoring
|
||||
{
|
||||
public class CatchScoreProcessor : ScoreProcessor<CatchHitObject>
|
||||
public class CatchScoreProcessor : ScoreProcessor
|
||||
{
|
||||
public CatchScoreProcessor(DrawableRuleset<CatchHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
public CatchScoreProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
private float hpDrainRate;
|
||||
|
||||
protected override void ApplyBeatmap(Beatmap<CatchHitObject> beatmap)
|
||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
base.ApplyBeatmap(beatmap);
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.Beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
|
||||
}
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(Beatmap);
|
||||
|
||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
|
||||
|
||||
|
@ -3,13 +3,11 @@
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Scoring
|
||||
{
|
||||
internal class ManiaScoreProcessor : ScoreProcessor<ManiaHitObject>
|
||||
internal class ManiaScoreProcessor : ScoreProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// The hit HP multiplier at OD = 0.
|
||||
@ -51,12 +49,12 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
/// </summary>
|
||||
private double hpMultiplier = 1;
|
||||
|
||||
public ManiaScoreProcessor(DrawableRuleset<ManiaHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
public ManiaScoreProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ApplyBeatmap(Beatmap<ManiaHitObject> beatmap)
|
||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
base.ApplyBeatmap(beatmap);
|
||||
|
||||
@ -65,7 +63,7 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
hpMissMultiplier = BeatmapDifficulty.DifficultyRange(difficulty.DrainRate, hp_multiplier_miss_min, hp_multiplier_miss_mid, hp_multiplier_miss_max);
|
||||
}
|
||||
|
||||
protected override void SimulateAutoplay(Beatmap<ManiaHitObject> beatmap)
|
||||
protected override void SimulateAutoplay(IBeatmap beatmap)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
|
@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages);
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(Beatmap);
|
||||
|
||||
public override int Variant => (int)(Beatmap.Stages.Count == 1 ? PlayfieldType.Single : PlayfieldType.Dual) + Beatmap.TotalColumns;
|
||||
|
||||
|
@ -5,22 +5,20 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Scoring
|
||||
{
|
||||
internal class OsuScoreProcessor : ScoreProcessor<OsuHitObject>
|
||||
internal class OsuScoreProcessor : ScoreProcessor
|
||||
{
|
||||
public OsuScoreProcessor(DrawableRuleset<OsuHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
public OsuScoreProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
private float hpDrainRate;
|
||||
|
||||
protected override void ApplyBeatmap(Beatmap<OsuHitObject> beatmap)
|
||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
base.ApplyBeatmap(beatmap);
|
||||
|
||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; // always show the gameplay cursor
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(Beatmap);
|
||||
|
||||
protected override Playfield CreatePlayfield() => new OsuPlayfield();
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
{
|
||||
internal class TaikoScoreProcessor : ScoreProcessor<TaikoHitObject>
|
||||
internal class TaikoScoreProcessor : ScoreProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// A value used for calculating <see cref="hpMultiplier"/>.
|
||||
@ -31,16 +31,16 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
/// </summary>
|
||||
private double hpMissMultiplier;
|
||||
|
||||
public TaikoScoreProcessor(DrawableRuleset<TaikoHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
public TaikoScoreProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ApplyBeatmap(Beatmap<TaikoHitObject> beatmap)
|
||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
base.ApplyBeatmap(beatmap);
|
||||
|
||||
hpMultiplier = 1 / (object_count_factor * beatmap.HitObjects.FindAll(o => o is Hit).Count * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
|
||||
hpMultiplier = 1 / (object_count_factor * beatmap.HitObjects.OfType<Hit>().Count() * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
|
||||
|
||||
hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
new BarLineGenerator<BarLine>(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar.Major ? new DrawableBarLineMajor(bar) : new DrawableBarLine(bar)));
|
||||
}
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(Beatmap);
|
||||
|
||||
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer();
|
||||
|
||||
|
@ -68,9 +68,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
};
|
||||
|
||||
AddStep("Set country", () => countryBindable.Value = country);
|
||||
AddAssert("Check scope is Performance", () => scope.Value == RankingsScope.Performance);
|
||||
AddStep("Set scope to Score", () => scope.Value = RankingsScope.Score);
|
||||
AddAssert("Check country is Null", () => countryBindable.Value == null);
|
||||
AddStep("Set country with no flag", () => countryBindable.Value = unknownCountry);
|
||||
}
|
||||
}
|
||||
|
@ -43,11 +43,6 @@ namespace osu.Game.Tests.Visual.Online
|
||||
FullName = "United States"
|
||||
};
|
||||
|
||||
AddStep("Set country", () => countryBindable.Value = countryA);
|
||||
AddAssert("Check scope is Performance", () => scope.Value == RankingsScope.Performance);
|
||||
AddStep("Set scope to Score", () => scope.Value = RankingsScope.Score);
|
||||
AddAssert("Check country is Null", () => countryBindable.Value == null);
|
||||
|
||||
AddStep("Set country 1", () => countryBindable.Value = countryA);
|
||||
AddStep("Set country 2", () => countryBindable.Value = countryB);
|
||||
AddStep("Set null country", () => countryBindable.Value = null);
|
||||
|
86
osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs
Normal file
86
osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs
Normal file
@ -0,0 +1,86 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Overlays.Rankings.Tables;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Overlays;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Users;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Overlays.Rankings;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
public class TestSceneRankingsOverlay : OsuTestScene
|
||||
{
|
||||
protected override bool UseOnlineAPI => true;
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(PerformanceTable),
|
||||
typeof(ScoresTable),
|
||||
typeof(CountriesTable),
|
||||
typeof(TableRowBackground),
|
||||
typeof(UserBasedTable),
|
||||
typeof(RankingsTable<>),
|
||||
typeof(RankingsOverlay)
|
||||
};
|
||||
|
||||
[Cached]
|
||||
private RankingsOverlay rankingsOverlay;
|
||||
|
||||
private readonly Bindable<Country> countryBindable = new Bindable<Country>();
|
||||
private readonly Bindable<RankingsScope> scope = new Bindable<RankingsScope>();
|
||||
|
||||
public TestSceneRankingsOverlay()
|
||||
{
|
||||
Add(rankingsOverlay = new TestRankingsOverlay
|
||||
{
|
||||
Country = { BindTarget = countryBindable },
|
||||
Scope = { BindTarget = scope },
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestShow()
|
||||
{
|
||||
AddStep("Show", rankingsOverlay.Show);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFlagScopeDependency()
|
||||
{
|
||||
AddStep("Set scope to Score", () => scope.Value = RankingsScope.Score);
|
||||
AddAssert("Check country is Null", () => countryBindable.Value == null);
|
||||
AddStep("Set country", () => countryBindable.Value = us_country);
|
||||
AddAssert("Check scope is Performance", () => scope.Value == RankingsScope.Performance);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestShowCountry()
|
||||
{
|
||||
AddStep("Show US", () => rankingsOverlay.ShowCountry(us_country));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHide()
|
||||
{
|
||||
AddStep("Hide", rankingsOverlay.Hide);
|
||||
}
|
||||
|
||||
private static readonly Country us_country = new Country
|
||||
{
|
||||
FlagName = "US",
|
||||
FullName = "United States"
|
||||
};
|
||||
|
||||
private class TestRankingsOverlay : RankingsOverlay
|
||||
{
|
||||
public new Bindable<Country> Country => base.Country;
|
||||
|
||||
public new Bindable<RankingsScope> Scope => base.Scope;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osu.Framework.IO.File;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Rulesets.Objects.Legacy;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
@ -112,7 +112,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
switch (pair.Key)
|
||||
{
|
||||
case @"AudioFilename":
|
||||
metadata.AudioFile = FileSafety.PathStandardise(pair.Value);
|
||||
metadata.AudioFile = pair.Value.ToStandardisedPath();
|
||||
break;
|
||||
|
||||
case @"AudioLeadIn":
|
||||
@ -300,12 +300,12 @@ namespace osu.Game.Beatmaps.Formats
|
||||
{
|
||||
case EventType.Background:
|
||||
string bgFilename = split[2].Trim('"');
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = FileSafety.PathStandardise(bgFilename);
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = bgFilename.ToStandardisedPath();
|
||||
break;
|
||||
|
||||
case EventType.Video:
|
||||
string videoFilename = split[2].Trim('"');
|
||||
beatmap.BeatmapInfo.Metadata.VideoFile = FileSafety.PathStandardise(videoFilename);
|
||||
beatmap.BeatmapInfo.Metadata.VideoFile = videoFilename.ToStandardisedPath();
|
||||
break;
|
||||
|
||||
case EventType.Break:
|
||||
|
@ -8,8 +8,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.IO.File;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Storyboards;
|
||||
|
||||
@ -335,6 +335,6 @@ namespace osu.Game.Beatmaps.Formats
|
||||
}
|
||||
}
|
||||
|
||||
private string cleanFilename(string path) => FileSafety.PathStandardise(path.Trim('"'));
|
||||
private string cleanFilename(string path) => path.Trim('"').ToStandardisedPath();
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ using osu.Game.Rulesets.Mods;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Storyboards;
|
||||
using osu.Framework.IO.File;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
@ -83,7 +82,10 @@ namespace osu.Game.Beatmaps
|
||||
/// <returns>The absolute path of the output file.</returns>
|
||||
public string Save()
|
||||
{
|
||||
var path = FileSafety.GetTempPath(Guid.NewGuid().ToString().Replace("-", string.Empty) + ".json");
|
||||
string directory = Path.Combine(Path.GetTempPath(), @"osu!");
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
var path = Path.Combine(directory, Guid.NewGuid().ToString().Replace("-", string.Empty) + ".json");
|
||||
using (var sw = new StreamWriter(path))
|
||||
sw.WriteLine(Beatmap.Serialize());
|
||||
return path;
|
||||
|
@ -13,7 +13,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.IO.File;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Threading;
|
||||
@ -493,7 +492,7 @@ namespace osu.Game.Database
|
||||
{
|
||||
fileInfos.Add(new TFileModel
|
||||
{
|
||||
Filename = FileSafety.PathStandardise(file.Substring(prefix.Length)),
|
||||
Filename = file.Substring(prefix.Length).ToStandardisedPath(),
|
||||
FileInfo = files.Add(s)
|
||||
});
|
||||
}
|
||||
|
@ -149,7 +149,15 @@ namespace osu.Game.Database
|
||||
lock (writeLock)
|
||||
{
|
||||
recycleThreadContexts();
|
||||
storage.DeleteDatabase(database_name);
|
||||
|
||||
try
|
||||
{
|
||||
storage.DeleteDatabase(database_name);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// for now we are not sure why file handles are kept open by EF, but this is generally only used in testing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,14 @@ namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetUserRankingsRequest : GetRankingsRequest<GetUsersResponse>
|
||||
{
|
||||
public readonly UserRankingsType Type;
|
||||
|
||||
private readonly string country;
|
||||
private readonly UserRankingsType type;
|
||||
|
||||
public GetUserRankingsRequest(RulesetInfo ruleset, UserRankingsType type = UserRankingsType.Performance, int page = 1, string country = null)
|
||||
: base(ruleset, page)
|
||||
{
|
||||
this.type = type;
|
||||
Type = type;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
@ -28,7 +29,7 @@ namespace osu.Game.Online.API.Requests
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override string TargetPostfix() => type.ToString().ToLowerInvariant();
|
||||
protected override string TargetPostfix() => Type.ToString().ToLowerInvariant();
|
||||
}
|
||||
|
||||
public enum UserRankingsType
|
||||
|
@ -74,13 +74,7 @@ namespace osu.Game.Overlays.Rankings
|
||||
base.LoadComplete();
|
||||
}
|
||||
|
||||
private void onScopeChanged(ValueChangedEvent<RankingsScope> scope)
|
||||
{
|
||||
scopeText.Text = scope.NewValue.ToString();
|
||||
|
||||
if (scope.NewValue != RankingsScope.Performance)
|
||||
Country.Value = null;
|
||||
}
|
||||
private void onScopeChanged(ValueChangedEvent<RankingsScope> scope) => scopeText.Text = scope.NewValue.ToString();
|
||||
|
||||
private void onCountryChanged(ValueChangedEvent<Country> country)
|
||||
{
|
||||
@ -90,8 +84,6 @@ namespace osu.Game.Overlays.Rankings
|
||||
return;
|
||||
}
|
||||
|
||||
Scope.Value = RankingsScope.Performance;
|
||||
|
||||
flag.Country = country.NewValue;
|
||||
flag.Show();
|
||||
}
|
||||
|
214
osu.Game/Overlays/RankingsOverlay.cs
Normal file
214
osu.Game/Overlays/RankingsOverlay.cs
Normal file
@ -0,0 +1,214 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Overlays.Rankings;
|
||||
using osu.Game.Users;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using System.Threading;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Overlays.Rankings.Tables;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public class RankingsOverlay : FullscreenOverlay
|
||||
{
|
||||
protected readonly Bindable<Country> Country = new Bindable<Country>();
|
||||
protected readonly Bindable<RankingsScope> Scope = new Bindable<RankingsScope>();
|
||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||
|
||||
private readonly BasicScrollContainer scrollFlow;
|
||||
private readonly Box background;
|
||||
private readonly Container tableContainer;
|
||||
private readonly DimmedLoadingLayer loading;
|
||||
|
||||
private APIRequest lastRequest;
|
||||
private CancellationTokenSource cancellationToken;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
|
||||
public RankingsOverlay()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
background = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
scrollFlow = new BasicScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ScrollbarVisible = false,
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new RankingsHeader
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Country = { BindTarget = Country },
|
||||
Scope = { BindTarget = Scope },
|
||||
Ruleset = { BindTarget = ruleset }
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
tableContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Margin = new MarginPadding { Vertical = 10 }
|
||||
},
|
||||
loading = new DimmedLoadingLayer(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colour)
|
||||
{
|
||||
Waves.FirstWaveColour = colour.Green;
|
||||
Waves.SecondWaveColour = colour.GreenLight;
|
||||
Waves.ThirdWaveColour = colour.GreenDark;
|
||||
Waves.FourthWaveColour = colour.GreenDarker;
|
||||
|
||||
background.Colour = OsuColour.Gray(0.1f);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
Country.BindValueChanged(_ =>
|
||||
{
|
||||
// if a country is requested, force performance scope.
|
||||
if (Country.Value != null)
|
||||
Scope.Value = RankingsScope.Performance;
|
||||
|
||||
Scheduler.AddOnce(loadNewContent);
|
||||
}, true);
|
||||
|
||||
Scope.BindValueChanged(_ =>
|
||||
{
|
||||
// country filtering is only valid for performance scope.
|
||||
if (Scope.Value != RankingsScope.Performance)
|
||||
Country.Value = null;
|
||||
|
||||
Scheduler.AddOnce(loadNewContent);
|
||||
}, true);
|
||||
|
||||
ruleset.BindValueChanged(_ => Scheduler.AddOnce(loadNewContent), true);
|
||||
|
||||
base.LoadComplete();
|
||||
}
|
||||
|
||||
public void ShowCountry(Country requested)
|
||||
{
|
||||
if (requested == null)
|
||||
return;
|
||||
|
||||
Show();
|
||||
|
||||
Country.Value = requested;
|
||||
}
|
||||
|
||||
private void loadNewContent()
|
||||
{
|
||||
loading.Show();
|
||||
|
||||
cancellationToken?.Cancel();
|
||||
lastRequest?.Cancel();
|
||||
|
||||
var request = createScopedRequest();
|
||||
lastRequest = request;
|
||||
|
||||
if (request == null)
|
||||
{
|
||||
loadTable(null);
|
||||
return;
|
||||
}
|
||||
|
||||
request.Success += () => loadTable(createTableFromResponse(request));
|
||||
request.Failure += _ => loadTable(null);
|
||||
|
||||
api.Queue(request);
|
||||
}
|
||||
|
||||
private APIRequest createScopedRequest()
|
||||
{
|
||||
switch (Scope.Value)
|
||||
{
|
||||
case RankingsScope.Performance:
|
||||
return new GetUserRankingsRequest(ruleset.Value, country: Country.Value?.FlagName);
|
||||
|
||||
case RankingsScope.Country:
|
||||
return new GetCountryRankingsRequest(ruleset.Value);
|
||||
|
||||
case RankingsScope.Score:
|
||||
return new GetUserRankingsRequest(ruleset.Value, UserRankingsType.Score);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Drawable createTableFromResponse(APIRequest request)
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case GetUserRankingsRequest userRequest:
|
||||
switch (userRequest.Type)
|
||||
{
|
||||
case UserRankingsType.Performance:
|
||||
return new PerformanceTable(1, userRequest.Result.Users);
|
||||
|
||||
case UserRankingsType.Score:
|
||||
return new ScoresTable(1, userRequest.Result.Users);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
case GetCountryRankingsRequest countryRequest:
|
||||
return new CountriesTable(1, countryRequest.Result.Countries);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void loadTable(Drawable table)
|
||||
{
|
||||
scrollFlow.ScrollToStart();
|
||||
|
||||
if (table == null)
|
||||
{
|
||||
tableContainer.Clear();
|
||||
loading.Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
LoadComponentAsync(table, t =>
|
||||
{
|
||||
loading.Hide();
|
||||
tableContainer.Child = table;
|
||||
}, (cancellationToken = new CancellationTokenSource()).Token);
|
||||
}
|
||||
}
|
||||
}
|
@ -13,13 +13,16 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Scoring
|
||||
{
|
||||
public abstract class ScoreProcessor
|
||||
public class ScoreProcessor
|
||||
{
|
||||
private const double base_portion = 0.3;
|
||||
private const double combo_portion = 0.7;
|
||||
private const double max_score = 1000000;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the <see cref="ScoreProcessor"/> is in a failed state.
|
||||
/// This may occur regardless of whether an <see cref="AllJudged"/> event is invoked.
|
||||
@ -67,11 +70,6 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// </summary>
|
||||
public readonly Bindable<IReadOnlyList<Mod>> Mods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="HitWindows"/> for this processor.
|
||||
/// </summary>
|
||||
public virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||
|
||||
/// <summary>
|
||||
/// The current rank.
|
||||
/// </summary>
|
||||
@ -90,132 +88,23 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// <summary>
|
||||
/// Whether all <see cref="Judgement"/>s have been processed.
|
||||
/// </summary>
|
||||
public virtual bool HasCompleted => false;
|
||||
|
||||
/// <summary>
|
||||
/// The total number of judged <see cref="HitObject"/>s at the current point in time.
|
||||
/// </summary>
|
||||
public int JudgedHits { get; protected set; }
|
||||
public bool HasCompleted => JudgedHits == MaxHits;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this ScoreProcessor has already triggered the failed state.
|
||||
/// </summary>
|
||||
public virtual bool HasFailed { get; private set; }
|
||||
public bool HasFailed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default conditions for failing.
|
||||
/// The maximum number of hits that can be judged.
|
||||
/// </summary>
|
||||
protected virtual bool DefaultFailCondition => Precision.AlmostBigger(Health.MinValue, Health.Value);
|
||||
|
||||
protected ScoreProcessor()
|
||||
{
|
||||
Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); };
|
||||
Accuracy.ValueChanged += delegate
|
||||
{
|
||||
Rank.Value = rankFrom(Accuracy.Value);
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToScoreProcessor>())
|
||||
Rank.Value = mod.AdjustRank(Rank.Value, Accuracy.Value);
|
||||
};
|
||||
}
|
||||
|
||||
private ScoreRank rankFrom(double acc)
|
||||
{
|
||||
if (acc == 1)
|
||||
return ScoreRank.X;
|
||||
if (acc > 0.95)
|
||||
return ScoreRank.S;
|
||||
if (acc > 0.9)
|
||||
return ScoreRank.A;
|
||||
if (acc > 0.8)
|
||||
return ScoreRank.B;
|
||||
if (acc > 0.7)
|
||||
return ScoreRank.C;
|
||||
|
||||
return ScoreRank.D;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this ScoreProcessor to a default state.
|
||||
/// </summary>
|
||||
/// <param name="storeResults">Whether to store the current state of the <see cref="ScoreProcessor"/> for future use.</param>
|
||||
protected virtual void Reset(bool storeResults)
|
||||
{
|
||||
TotalScore.Value = 0;
|
||||
Accuracy.Value = 1;
|
||||
Health.Value = 1;
|
||||
Combo.Value = 0;
|
||||
Rank.Value = ScoreRank.X;
|
||||
HighestCombo.Value = 0;
|
||||
|
||||
JudgedHits = 0;
|
||||
|
||||
HasFailed = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the score is in a failed state and notifies subscribers.
|
||||
/// <para>
|
||||
/// This can only ever notify subscribers once.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
protected void UpdateFailed(JudgementResult result)
|
||||
{
|
||||
if (HasFailed)
|
||||
return;
|
||||
|
||||
if (!DefaultFailCondition && FailConditions?.Invoke(this, result) != true)
|
||||
return;
|
||||
|
||||
if (Failed?.Invoke() != false)
|
||||
HasFailed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies subscribers of <see cref="NewJudgement"/> that a new judgement has occurred.
|
||||
/// </summary>
|
||||
/// <param name="result">The judgement scoring result to notify subscribers of.</param>
|
||||
protected void NotifyNewJudgement(JudgementResult result)
|
||||
{
|
||||
NewJudgement?.Invoke(result);
|
||||
|
||||
if (HasCompleted)
|
||||
AllJudged?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve a score populated with data for the current play this processor is responsible for.
|
||||
/// </summary>
|
||||
public virtual void PopulateScore(ScoreInfo score)
|
||||
{
|
||||
score.TotalScore = (long)Math.Round(TotalScore.Value);
|
||||
score.Combo = Combo.Value;
|
||||
score.MaxCombo = HighestCombo.Value;
|
||||
score.Accuracy = Math.Round(Accuracy.Value, 4);
|
||||
score.Rank = Rank.Value;
|
||||
score.Date = DateTimeOffset.Now;
|
||||
|
||||
var hitWindows = CreateHitWindows();
|
||||
|
||||
foreach (var result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r)))
|
||||
score.Statistics[result] = GetStatistic(result);
|
||||
}
|
||||
|
||||
public abstract int GetStatistic(HitResult result);
|
||||
|
||||
public abstract double GetStandardisedScore();
|
||||
}
|
||||
|
||||
public class ScoreProcessor<TObject> : ScoreProcessor
|
||||
where TObject : HitObject
|
||||
{
|
||||
private const double base_portion = 0.3;
|
||||
private const double combo_portion = 0.7;
|
||||
private const double max_score = 1000000;
|
||||
|
||||
public sealed override bool HasCompleted => JudgedHits == MaxHits;
|
||||
|
||||
protected int MaxHits { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The total number of judged <see cref="HitObject"/>s at the current point in time.
|
||||
/// </summary>
|
||||
public int JudgedHits { get; private set; }
|
||||
|
||||
private double maxHighestCombo;
|
||||
|
||||
private double maxBaseScore;
|
||||
@ -225,17 +114,22 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
private double scoreMultiplier = 1;
|
||||
|
||||
public ScoreProcessor(DrawableRuleset<TObject> drawableRuleset)
|
||||
public ScoreProcessor(IBeatmap beatmap)
|
||||
{
|
||||
Debug.Assert(base_portion + combo_portion == 1.0);
|
||||
|
||||
drawableRuleset.OnNewResult += applyResult;
|
||||
drawableRuleset.OnRevertResult += revertResult;
|
||||
Combo.ValueChanged += combo => HighestCombo.Value = Math.Max(HighestCombo.Value, combo.NewValue);
|
||||
Accuracy.ValueChanged += accuracy =>
|
||||
{
|
||||
Rank.Value = rankFrom(accuracy.NewValue);
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToScoreProcessor>())
|
||||
Rank.Value = mod.AdjustRank(Rank.Value, accuracy.NewValue);
|
||||
};
|
||||
|
||||
ApplyBeatmap(drawableRuleset.Beatmap);
|
||||
ApplyBeatmap(beatmap);
|
||||
|
||||
Reset(false);
|
||||
SimulateAutoplay(drawableRuleset.Beatmap);
|
||||
SimulateAutoplay(beatmap);
|
||||
Reset(true);
|
||||
|
||||
if (maxBaseScore == 0 || maxHighestCombo == 0)
|
||||
@ -257,19 +151,19 @@ namespace osu.Game.Rulesets.Scoring
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies any properties of the <see cref="Beatmap{TObject}"/> which affect scoring to this <see cref="ScoreProcessor{TObject}"/>.
|
||||
/// Applies any properties of the <see cref="IBeatmap"/> which affect scoring to this <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The <see cref="Beatmap{TObject}"/> to read properties from.</param>
|
||||
protected virtual void ApplyBeatmap(Beatmap<TObject> beatmap)
|
||||
/// <param name="beatmap">The <see cref="IBeatmap"/> to read properties from.</param>
|
||||
protected virtual void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simulates an autoplay of the <see cref="Beatmap{TObject}"/> to determine scoring values.
|
||||
/// Simulates an autoplay of the <see cref="IBeatmap"/> to determine scoring values.
|
||||
/// </summary>
|
||||
/// <remarks>This provided temporarily. DO NOT USE.</remarks>
|
||||
/// <param name="beatmap">The <see cref="Beatmap{TObject}"/> to simulate.</param>
|
||||
protected virtual void SimulateAutoplay(Beatmap<TObject> beatmap)
|
||||
/// <param name="beatmap">The <see cref="IBeatmap"/> to simulate.</param>
|
||||
protected virtual void SimulateAutoplay(IBeatmap beatmap)
|
||||
{
|
||||
foreach (var obj in beatmap.HitObjects)
|
||||
simulate(obj);
|
||||
@ -289,7 +183,7 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
result.Type = judgement.MaxResult;
|
||||
|
||||
applyResult(result);
|
||||
ApplyResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,22 +191,26 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// Applies the score change of a <see cref="JudgementResult"/> to this <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
/// <param name="result">The <see cref="JudgementResult"/> to apply.</param>
|
||||
private void applyResult(JudgementResult result)
|
||||
public void ApplyResult(JudgementResult result)
|
||||
{
|
||||
ApplyResult(result);
|
||||
updateScore();
|
||||
ApplyResultInternal(result);
|
||||
|
||||
UpdateFailed(result);
|
||||
NotifyNewJudgement(result);
|
||||
updateScore();
|
||||
updateFailed(result);
|
||||
|
||||
NewJudgement?.Invoke(result);
|
||||
|
||||
if (HasCompleted)
|
||||
AllJudged?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the score change of a <see cref="JudgementResult"/> that was applied to this <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
/// <param name="result">The judgement scoring result.</param>
|
||||
private void revertResult(JudgementResult result)
|
||||
public void RevertResult(JudgementResult result)
|
||||
{
|
||||
RevertResult(result);
|
||||
RevertResultInternal(result);
|
||||
updateScore();
|
||||
}
|
||||
|
||||
@ -322,10 +220,10 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// Applies the score change of a <see cref="JudgementResult"/> to this <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Any changes applied via this method can be reverted via <see cref="RevertResult"/>.
|
||||
/// Any changes applied via this method can be reverted via <see cref="RevertResultInternal"/>.
|
||||
/// </remarks>
|
||||
/// <param name="result">The <see cref="JudgementResult"/> to apply.</param>
|
||||
protected virtual void ApplyResult(JudgementResult result)
|
||||
protected virtual void ApplyResultInternal(JudgementResult result)
|
||||
{
|
||||
result.ComboAtJudgement = Combo.Value;
|
||||
result.HighestComboAtJudgement = HighestCombo.Value;
|
||||
@ -372,10 +270,10 @@ namespace osu.Game.Rulesets.Scoring
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the score change of a <see cref="JudgementResult"/> that was applied to this <see cref="ScoreProcessor"/> via <see cref="ApplyResult"/>.
|
||||
/// Reverts the score change of a <see cref="JudgementResult"/> that was applied to this <see cref="ScoreProcessor"/> via <see cref="ApplyResultInternal"/>.
|
||||
/// </summary>
|
||||
/// <param name="result">The judgement scoring result.</param>
|
||||
protected virtual void RevertResult(JudgementResult result)
|
||||
protected virtual void RevertResultInternal(JudgementResult result)
|
||||
{
|
||||
Combo.Value = result.ComboAtJudgement;
|
||||
HighestCombo.Value = result.HighestComboAtJudgement;
|
||||
@ -432,11 +330,49 @@ namespace osu.Game.Rulesets.Scoring
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetStatistic(HitResult result) => scoreResultCounts.GetOrDefault(result);
|
||||
/// <summary>
|
||||
/// Checks if the score is in a failed state and notifies subscribers.
|
||||
/// <para>
|
||||
/// This can only ever notify subscribers once.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
private void updateFailed(JudgementResult result)
|
||||
{
|
||||
if (HasFailed)
|
||||
return;
|
||||
|
||||
public override double GetStandardisedScore() => getScore(ScoringMode.Standardised);
|
||||
if (!DefaultFailCondition && FailConditions?.Invoke(this, result) != true)
|
||||
return;
|
||||
|
||||
protected override void Reset(bool storeResults)
|
||||
if (Failed?.Invoke() != false)
|
||||
HasFailed = true;
|
||||
}
|
||||
|
||||
private ScoreRank rankFrom(double acc)
|
||||
{
|
||||
if (acc == 1)
|
||||
return ScoreRank.X;
|
||||
if (acc > 0.95)
|
||||
return ScoreRank.S;
|
||||
if (acc > 0.9)
|
||||
return ScoreRank.A;
|
||||
if (acc > 0.8)
|
||||
return ScoreRank.B;
|
||||
if (acc > 0.7)
|
||||
return ScoreRank.C;
|
||||
|
||||
return ScoreRank.D;
|
||||
}
|
||||
|
||||
public int GetStatistic(HitResult result) => scoreResultCounts.GetOrDefault(result);
|
||||
|
||||
public double GetStandardisedScore() => getScore(ScoringMode.Standardised);
|
||||
|
||||
/// <summary>
|
||||
/// Resets this ScoreProcessor to a default state.
|
||||
/// </summary>
|
||||
/// <param name="storeResults">Whether to store the current state of the <see cref="ScoreProcessor"/> for future use.</param>
|
||||
protected virtual void Reset(bool storeResults)
|
||||
{
|
||||
scoreResultCounts.Clear();
|
||||
|
||||
@ -447,13 +383,49 @@ namespace osu.Game.Rulesets.Scoring
|
||||
maxBaseScore = baseScore;
|
||||
}
|
||||
|
||||
base.Reset(storeResults);
|
||||
|
||||
JudgedHits = 0;
|
||||
baseScore = 0;
|
||||
rollingMaxBaseScore = 0;
|
||||
bonusScore = 0;
|
||||
|
||||
TotalScore.Value = 0;
|
||||
Accuracy.Value = 1;
|
||||
Health.Value = 1;
|
||||
Combo.Value = 0;
|
||||
Rank.Value = ScoreRank.X;
|
||||
HighestCombo.Value = 0;
|
||||
|
||||
HasFailed = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve a score populated with data for the current play this processor is responsible for.
|
||||
/// </summary>
|
||||
public virtual void PopulateScore(ScoreInfo score)
|
||||
{
|
||||
score.TotalScore = (long)Math.Round(TotalScore.Value);
|
||||
score.Combo = Combo.Value;
|
||||
score.MaxCombo = HighestCombo.Value;
|
||||
score.Accuracy = Math.Round(Accuracy.Value, 4);
|
||||
score.Rank = Rank.Value;
|
||||
score.Date = DateTimeOffset.Now;
|
||||
|
||||
var hitWindows = CreateHitWindows();
|
||||
|
||||
foreach (var result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r)))
|
||||
score.Statistics[result] = GetStatistic(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default conditions for failing.
|
||||
/// </summary>
|
||||
protected virtual bool DefaultFailCondition => Precision.AlmostBigger(Health.MinValue, Health.Value);
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="HitWindows"/> for this processor.
|
||||
/// </summary>
|
||||
public virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="JudgementResult"/> that represents the scoring result for a <see cref="HitObject"/>.
|
||||
/// </summary>
|
||||
|
@ -45,6 +45,10 @@ namespace osu.Game.Rulesets.UI
|
||||
public abstract class DrawableRuleset<TObject> : DrawableRuleset, IProvideCursor, ICanAttachKeyCounter
|
||||
where TObject : HitObject
|
||||
{
|
||||
public override event Action<JudgementResult> OnNewResult;
|
||||
|
||||
public override event Action<JudgementResult> OnRevertResult;
|
||||
|
||||
/// <summary>
|
||||
/// The selected variant.
|
||||
/// </summary>
|
||||
@ -91,16 +95,6 @@ namespace osu.Game.Rulesets.UI
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="JudgementResult"/> has been applied by a <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
public event Action<JudgementResult> OnNewResult;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="JudgementResult"/> is being reverted by a <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
public event Action<JudgementResult> OnRevertResult;
|
||||
|
||||
/// <summary>
|
||||
/// The beatmap.
|
||||
/// </summary>
|
||||
@ -309,7 +303,7 @@ namespace osu.Game.Rulesets.UI
|
||||
/// <returns>The Playfield.</returns>
|
||||
protected abstract Playfield CreatePlayfield();
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor<TObject>(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(Beatmap);
|
||||
|
||||
/// <summary>
|
||||
/// Applies the active mods to this DrawableRuleset.
|
||||
@ -366,6 +360,16 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
public abstract class DrawableRuleset : CompositeDrawable
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="JudgementResult"/> has been applied by a <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
public abstract event Action<JudgementResult> OnNewResult;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="JudgementResult"/> is being reverted by a <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
public abstract event Action<JudgementResult> OnRevertResult;
|
||||
|
||||
/// <summary>
|
||||
/// Whether a replay is currently loaded.
|
||||
/// </summary>
|
||||
|
@ -4,7 +4,6 @@
|
||||
using System;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -29,14 +28,13 @@ using osu.Game.Input.Bindings;
|
||||
using osu.Game.Screens.Edit.Compose;
|
||||
using osu.Game.Screens.Edit.Setup;
|
||||
using osu.Game.Screens.Edit.Timing;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
public class Editor : OsuScreen, IKeyBindingHandler<GlobalAction>
|
||||
public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4");
|
||||
|
||||
public override float BackgroundParallaxAmount => 0.1f;
|
||||
|
||||
public override bool AllowBackButton => false;
|
||||
@ -250,8 +248,12 @@ namespace osu.Game.Screens.Edit
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
// todo: temporary. we want to be applying dim using the UserDimContainer eventually.
|
||||
Background.FadeColour(Color4.DarkGray, 500);
|
||||
|
||||
Background.EnableUserDim.Value = false;
|
||||
Background.BlurAmount.Value = 0;
|
||||
|
||||
resetTrack(true);
|
||||
}
|
||||
|
||||
|
@ -140,6 +140,9 @@ namespace osu.Game.Screens.Play
|
||||
// bind clock into components that require it
|
||||
DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused);
|
||||
|
||||
DrawableRuleset.OnNewResult += ScoreProcessor.ApplyResult;
|
||||
DrawableRuleset.OnRevertResult += ScoreProcessor.RevertResult;
|
||||
|
||||
// Bind ScoreProcessor to ourselves
|
||||
ScoreProcessor.AllJudged += onCompletion;
|
||||
ScoreProcessor.Failed += onFail;
|
||||
|
@ -1,11 +1,12 @@
|
||||
// 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;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Users
|
||||
{
|
||||
public class Country
|
||||
public class Country : IEquatable<Country>
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of this country.
|
||||
@ -18,5 +19,7 @@ namespace osu.Game.Users
|
||||
/// </summary>
|
||||
[JsonProperty(@"code")]
|
||||
public string FlagName;
|
||||
|
||||
public bool Equals(Country other) => FlagName == other?.FlagName;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
// 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.Input.Events;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Users.Drawables
|
||||
{
|
||||
@ -34,5 +37,14 @@ namespace osu.Game.Users.Drawables
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
};
|
||||
}
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private RankingsOverlay rankingsOverlay { get; set; }
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
rankingsOverlay?.ShowCountry(Country);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1210.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1212.0" />
|
||||
<PackageReference Include="Sentry" Version="1.2.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
|
@ -74,7 +74,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.1210.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.1212.0" />
|
||||
</ItemGroup>
|
||||
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
@ -82,7 +82,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1210.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1212.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
|
Loading…
Reference in New Issue
Block a user