mirror of
https://github.com/ppy/osu.git
synced 2026-05-16 05:32:35 +08:00
Compare commits
635 Commits
@@ -15,7 +15,9 @@ This is still heavily under development and is not intended for end-user use. Th
|
||||
|
||||
We welcome all contributions, but keep in mind that we already have a lot of the UI designed. If you wish to work on something with the intention on having it included in the official distribution, please open an issue for discussion and we will give you what you need from a design perspective to proceed. If you want to make *changes* to the design, we recommend you open an issue with your intentions before spending too much time, to ensure no effort is wasted.
|
||||
|
||||
Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://www.bountysource.com/teams/ppy). If you're unsure of what you can help with, check out the [list of open issues](https://github.com/ppy/osu-framework/issues).
|
||||
Please make sure you are familiar with the [development and testing](https://github.com/ppy/osu-framework/wiki/Development-and-Testing) procedure we have set up. New component development, and where possible, bug fixing and debugging existing components **should always be done under VisualTests**.
|
||||
|
||||
Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://www.bountysource.com/teams/ppy). If you're unsure of what you can help with, check out the [list of open issues](https://github.com/ppy/osu/issues).
|
||||
|
||||
Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured; with any libraries we are using; with any processes involved with contributing, *please* bring it up. I welcome all feedback so we can make contributing to this project as pain-free as possible.
|
||||
|
||||
|
||||
+1
-1
Submodule osu-framework updated: 5986f21268...d92cec7645
+1
-1
Submodule osu-resources updated: a4418111f8...4287ee8043
@@ -13,7 +13,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
|
||||
<add key="ProjectName" value="osu.Desktop" />
|
||||
<add key="NuSpecName" value="osu.Desktop\osu.nuspec" />
|
||||
<add key="SolutionName" value="osu" />
|
||||
<add key="TargetName" value="Client\osu.Desktop" />
|
||||
<add key="TargetName" value="osu.Desktop" />
|
||||
<add key="PackageName" value="osulazer" />
|
||||
<add key="IconName" value="lazer.ico" />
|
||||
<add key="CodeSigningCertificate" value="" />
|
||||
|
||||
@@ -145,6 +145,8 @@ namespace osu.Desktop.Deploy
|
||||
/// </summary>
|
||||
private static void checkReleaseFiles()
|
||||
{
|
||||
if (!canGitHub) return;
|
||||
|
||||
var releaseLines = getReleaseLines();
|
||||
|
||||
//ensure we have all files necessary
|
||||
@@ -157,6 +159,8 @@ namespace osu.Desktop.Deploy
|
||||
|
||||
private static void pruneReleases()
|
||||
{
|
||||
if (!canGitHub) return;
|
||||
|
||||
write("Pruning RELEASES...");
|
||||
|
||||
var releaseLines = getReleaseLines().ToList();
|
||||
@@ -190,7 +194,7 @@ namespace osu.Desktop.Deploy
|
||||
|
||||
private static void uploadBuild(string version)
|
||||
{
|
||||
if (string.IsNullOrEmpty(GitHubAccessToken) || string.IsNullOrEmpty(codeSigningCertPath))
|
||||
if (!canGitHub || string.IsNullOrEmpty(CodeSigningCertificate))
|
||||
return;
|
||||
|
||||
write("Publishing to GitHub...");
|
||||
@@ -228,8 +232,12 @@ namespace osu.Desktop.Deploy
|
||||
|
||||
private static void openGitHubReleasePage() => Process.Start(GitHubReleasePage);
|
||||
|
||||
private static bool canGitHub => !string.IsNullOrEmpty(GitHubAccessToken);
|
||||
|
||||
private static void checkGitHubReleases()
|
||||
{
|
||||
if (!canGitHub) return;
|
||||
|
||||
write("Checking GitHub releases...");
|
||||
var req = new JsonWebRequest<List<GitHubRelease>>($"{GitHubApiEndpoint}");
|
||||
req.AuthenticatedBlockingPerform();
|
||||
@@ -390,7 +398,7 @@ namespace osu.Desktop.Deploy
|
||||
|
||||
public static void AuthenticatedBlockingPerform(this WebRequest r)
|
||||
{
|
||||
r.Headers.Add("Authorization", $"token {GitHubAccessToken}");
|
||||
r.AddHeader("Authorization", $"token {GitHubAccessToken}");
|
||||
r.Perform();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,12 @@ namespace osu.Desktop
|
||||
{
|
||||
internal class OsuGameDesktop : OsuGame
|
||||
{
|
||||
private readonly bool noVersionOverlay;
|
||||
|
||||
public OsuGameDesktop(string[] args = null)
|
||||
: base(args)
|
||||
{
|
||||
noVersionOverlay = args?.Any(a => a == "--no-version-overlay") ?? false;
|
||||
}
|
||||
|
||||
public override Storage GetStorageForStableInstall()
|
||||
@@ -79,11 +82,14 @@ namespace osu.Desktop
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
|
||||
if (!noVersionOverlay)
|
||||
{
|
||||
Add(v);
|
||||
v.State = Visibility.Visible;
|
||||
});
|
||||
LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
|
||||
{
|
||||
Add(v);
|
||||
v.State = Visibility.Visible;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetHost(GameHost host)
|
||||
@@ -106,7 +112,7 @@ namespace osu.Desktop
|
||||
var filePaths = new [] { e.FileName };
|
||||
|
||||
if (filePaths.All(f => Path.GetExtension(f) == @".osz"))
|
||||
Task.Run(() => BeatmapManager.Import(filePaths));
|
||||
Task.Factory.StartNew(() => BeatmapManager.Import(filePaths), TaskCreationOptions.LongRunning);
|
||||
else if (filePaths.All(f => Path.GetExtension(f) == @".osr"))
|
||||
Task.Run(() =>
|
||||
{
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Http;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Graphics;
|
||||
@@ -198,10 +197,9 @@ namespace osu.Desktop.Overlays
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
catch (Exception)
|
||||
{
|
||||
//likely have no internet connection.
|
||||
//we'll ignore this and retry later.
|
||||
// we'll ignore this and retry later. can be triggered by no internet connection or thread abortion.
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -233,7 +231,8 @@ namespace osu.Desktop.Overlays
|
||||
Text = @"Update ready to install. Click to restart!",
|
||||
Activated = () =>
|
||||
{
|
||||
UpdateManager.RestartAppWhenExited();
|
||||
// Squirrel returns execution to us after the update process is started, so it's safe to use Wait() here
|
||||
UpdateManager.RestartAppWhenExited().Wait();
|
||||
game.GracefullyExit();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
protected override IEnumerable<CatchBaseHit> ConvertHitObject(HitObject obj, Beatmap beatmap)
|
||||
{
|
||||
var curveData = obj as IHasCurve;
|
||||
var positionData = obj as IHasPosition;
|
||||
var positionData = obj as IHasXPosition;
|
||||
var comboData = obj as IHasCombo;
|
||||
|
||||
if (positionData == null)
|
||||
|
||||
@@ -14,11 +14,8 @@ namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
}
|
||||
|
||||
protected override double CalculateInternal(Dictionary<string, string> categoryDifficulty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public override double Calculate(Dictionary<string, string> categoryDifficulty = null) => 0;
|
||||
|
||||
protected override BeatmapConverter<CatchBaseHit> CreateBeatmapConverter() => new CatchBeatmapConverter();
|
||||
protected override BeatmapConverter<CatchBaseHit> CreateBeatmapConverter(Beatmap beatmap) => new CatchBeatmapConverter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new CatchDifficultyCalculator(beatmap);
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new CatchDifficultyCalculator(beatmap);
|
||||
|
||||
public override int LegacyID => 2;
|
||||
|
||||
|
||||
@@ -138,8 +138,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
Pattern newPattern = conversion.Generate();
|
||||
lastPattern = newPattern;
|
||||
|
||||
var stairPatternGenerator = (HitObjectPatternGenerator)conversion;
|
||||
lastStair = stairPatternGenerator.StairType;
|
||||
var stairPatternGenerator = conversion as HitObjectPatternGenerator;
|
||||
lastStair = stairPatternGenerator?.StairType ?? lastStair;
|
||||
|
||||
return newPattern.HitObjects;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,8 @@ namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
}
|
||||
|
||||
protected override double CalculateInternal(Dictionary<string, string> categoryDifficulty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public override double Calculate(Dictionary<string, string> categoryDifficulty = null) => 0;
|
||||
|
||||
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter() => new ManiaBeatmapConverter(true, (int)Math.Max(1, Math.Round(Beatmap.BeatmapInfo.BaseDifficulty.CircleSize)));
|
||||
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter(Beatmap beatmap) => new ManiaBeatmapConverter(true, (int)Math.Max(1, Math.Round(beatmap.BeatmapInfo.BaseDifficulty.CircleSize)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new ManiaDifficultyCalculator(beatmap);
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new ManiaDifficultyCalculator(beatmap);
|
||||
|
||||
public override int LegacyID => 3;
|
||||
|
||||
|
||||
@@ -86,18 +86,17 @@ namespace osu.Game.Rulesets.Mania.Mods
|
||||
public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) };
|
||||
}
|
||||
|
||||
public class ManiaModRandom : Mod, IApplicableMod<ManiaHitObject>
|
||||
public class ManiaModRandom : Mod, IApplicableToRulesetContainer<ManiaHitObject>
|
||||
{
|
||||
public override string Name => "Random";
|
||||
public override string ShortenedName => "RD";
|
||||
public override FontAwesome Icon => FontAwesome.fa_osu_dice;
|
||||
public override FontAwesome Icon => FontAwesome.fa_osu_dice;
|
||||
public override string Description => @"Shuffle around the notes!";
|
||||
public override double ScoreMultiplier => 1;
|
||||
|
||||
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
||||
{
|
||||
int availableColumns = ((ManiaRulesetContainer)rulesetContainer).AvailableColumns;
|
||||
|
||||
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList();
|
||||
|
||||
rulesetContainer.Objects.OfType<ManiaHitObject>().ForEach(h => h.Column = shuffledColumns[h.Column]);
|
||||
@@ -188,6 +187,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
||||
|
||||
base.ApplyToRulesetContainer(rulesetContainer);
|
||||
}
|
||||
|
||||
protected override Score CreateReplayScore(Beatmap<ManiaHitObject> beatmap) => new Score
|
||||
{
|
||||
User = new User { Username = "osu!topus!" },
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
switch (State)
|
||||
switch (State.Value)
|
||||
{
|
||||
case ArmedState.Hit:
|
||||
AccentColour = Color4.Green;
|
||||
|
||||
@@ -26,8 +26,6 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
private const double start_time = 500;
|
||||
private const double duration = 500;
|
||||
|
||||
public override string Description => @"Mania playfield";
|
||||
|
||||
protected override double TimePerAction => 200;
|
||||
|
||||
private RulesetInfo maniaRuleset;
|
||||
|
||||
@@ -57,8 +57,10 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500).Expire();
|
||||
this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500);
|
||||
inner.FadeOut(250);
|
||||
|
||||
Expire(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ using osu.Game.Rulesets.Osu.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
@@ -33,22 +32,29 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
public override double ScoreMultiplier => 1.06;
|
||||
}
|
||||
|
||||
public class OsuModHardRock : ModHardRock, IApplicableMod<OsuHitObject>
|
||||
public class OsuModHardRock : ModHardRock, IApplicableToHitObject<OsuHitObject>
|
||||
{
|
||||
public override double ScoreMultiplier => 1.06;
|
||||
public override bool Ranked => true;
|
||||
|
||||
public void ApplyToRulesetContainer(RulesetContainer<OsuHitObject> rulesetContainer)
|
||||
public void ApplyToHitObject(OsuHitObject hitObject)
|
||||
{
|
||||
hitObject.Position = new Vector2(hitObject.Position.X, OsuPlayfield.BASE_SIZE.Y - hitObject.Y);
|
||||
|
||||
var slider = hitObject as Slider;
|
||||
if (slider == null)
|
||||
return;
|
||||
|
||||
var newControlPoints = new List<Vector2>();
|
||||
slider.ControlPoints.ForEach(c => newControlPoints.Add(new Vector2(c.X, OsuPlayfield.BASE_SIZE.Y - c.Y)));
|
||||
|
||||
slider.ControlPoints = newControlPoints;
|
||||
slider.Curve?.Calculate(); // Recalculate the slider curve
|
||||
}
|
||||
|
||||
public void ApplyToHitObjects(RulesetContainer<OsuHitObject> rulesetContainer)
|
||||
{
|
||||
rulesetContainer.Objects.OfType<OsuHitObject>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Y));
|
||||
rulesetContainer.Objects.OfType<Slider>().ForEach(s =>
|
||||
{
|
||||
var newControlPoints = new List<Vector2>();
|
||||
s.ControlPoints.ForEach(c => newControlPoints.Add(new Vector2(c.X, OsuPlayfield.BASE_SIZE.Y - c.Y)));
|
||||
|
||||
s.ControlPoints = newControlPoints;
|
||||
s.Curve?.Calculate(); // Recalculate the slider curve
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
||||
{
|
||||
private const float width = 8;
|
||||
|
||||
public override bool RemoveWhenNotAlive => false;
|
||||
|
||||
public FollowPoint()
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
@@ -52,9 +52,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RemoveCompletedTransforms => false;
|
||||
|
||||
private void update()
|
||||
{
|
||||
Clear();
|
||||
|
||||
if (hitObjects == null)
|
||||
return;
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
},
|
||||
ApproachCircle = new ApproachCircle
|
||||
{
|
||||
Alpha = 0,
|
||||
Scale = new Vector2(4),
|
||||
Colour = AccentColour,
|
||||
}
|
||||
};
|
||||
@@ -82,21 +84,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
});
|
||||
}
|
||||
|
||||
protected override void UpdateInitialState()
|
||||
{
|
||||
base.UpdateInitialState();
|
||||
|
||||
// sane defaults
|
||||
ring.Show();
|
||||
circle.Show();
|
||||
number.Show();
|
||||
glow.Show();
|
||||
|
||||
ApproachCircle.Hide();
|
||||
ApproachCircle.ScaleTo(new Vector2(4));
|
||||
explode.Hide();
|
||||
}
|
||||
|
||||
protected override void UpdatePreemptState()
|
||||
{
|
||||
base.UpdatePreemptState();
|
||||
|
||||
@@ -23,12 +23,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
protected sealed override void UpdateState(ArmedState state)
|
||||
{
|
||||
FinishTransforms();
|
||||
double transformTime = HitObject.StartTime - TIME_PREEMPT;
|
||||
|
||||
using (BeginAbsoluteSequence(HitObject.StartTime - TIME_PREEMPT, true))
|
||||
base.ApplyTransformsAt(transformTime, true);
|
||||
base.ClearTransformsAfter(transformTime, true);
|
||||
|
||||
using (BeginAbsoluteSequence(transformTime, true))
|
||||
{
|
||||
UpdateInitialState();
|
||||
|
||||
UpdatePreemptState();
|
||||
|
||||
using (BeginDelayedSequence(TIME_PREEMPT + (Judgements.FirstOrDefault()?.TimeOffset ?? 0), true))
|
||||
@@ -36,11 +37,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateInitialState()
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
protected virtual void UpdatePreemptState()
|
||||
{
|
||||
this.FadeIn(TIME_FADEIN);
|
||||
@@ -50,6 +46,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
}
|
||||
|
||||
// Todo: At some point we need to move these to DrawableHitObject after ensuring that all other Rulesets apply
|
||||
// transforms in the same way and don't rely on them not being cleared
|
||||
public override void ClearTransformsAfter(double time, bool propagateChildren = false, string targetMember = null) { }
|
||||
public override void ApplyTransformsAt(double time, bool propagateChildren = false) { }
|
||||
|
||||
private OsuInputManager osuActionInputManager;
|
||||
internal OsuInputManager OsuActionInputManager => osuActionInputManager ?? (osuActionInputManager = GetContainingInputManager() as OsuInputManager);
|
||||
}
|
||||
|
||||
@@ -18,9 +18,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
public double FadeInTime;
|
||||
public double FadeOutTime;
|
||||
|
||||
public override bool RemoveWhenNotAlive => false;
|
||||
|
||||
public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider) : base(repeatPoint)
|
||||
public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider)
|
||||
: base(repeatPoint)
|
||||
{
|
||||
this.repeatPoint = repeatPoint;
|
||||
this.drawableSlider = drawableSlider;
|
||||
@@ -28,6 +27,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Blending = BlendingMode.Additive;
|
||||
Origin = Anchor.Centre;
|
||||
Scale = new Vector2(0.5f);
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@@ -51,12 +51,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
var animIn = Math.Min(150, repeatPoint.StartTime - FadeInTime);
|
||||
|
||||
this.Animate(
|
||||
d => d.FadeIn(animIn),
|
||||
d => d.ScaleTo(0.5f).ScaleTo(1.2f, animIn)
|
||||
).Then(
|
||||
d => d.ScaleTo(1, 150, Easing.Out)
|
||||
);
|
||||
this.FadeIn(animIn).ScaleTo(1.2f, animIn)
|
||||
.Then()
|
||||
.ScaleTo(1, 150, Easing.Out);
|
||||
}
|
||||
|
||||
protected override void UpdateCurrentState(ArmedState state)
|
||||
|
||||
@@ -43,7 +43,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
ball = new SliderBall(s)
|
||||
{
|
||||
Scale = new Vector2(s.Scale),
|
||||
AccentColour = AccentColour
|
||||
AccentColour = AccentColour,
|
||||
AlwaysPresent = true,
|
||||
Alpha = 0
|
||||
},
|
||||
initialCircle = new DrawableHitCircle(new HitCircle
|
||||
{
|
||||
@@ -148,16 +150,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateInitialState()
|
||||
{
|
||||
base.UpdateInitialState();
|
||||
body.Alpha = 1;
|
||||
|
||||
//we need to be present to handle input events. note that we still don't get enough events (we don't get a position if the mouse hasn't moved since the slider appeared).
|
||||
ball.AlwaysPresent = true;
|
||||
ball.Alpha = 0;
|
||||
}
|
||||
|
||||
protected override void UpdateCurrentState(ArmedState state)
|
||||
{
|
||||
ball.FadeIn();
|
||||
|
||||
@@ -20,8 +20,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
public bool Tracking;
|
||||
|
||||
public override bool RemoveWhenNotAlive => false;
|
||||
|
||||
public override bool DisplayJudgement => false;
|
||||
|
||||
public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick)
|
||||
|
||||
@@ -101,14 +101,21 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
// If the current time is between the start and end of the slider, we should track mouse input regardless of the cursor position.
|
||||
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => canCurrentlyTrack || base.ReceiveMouseInputAt(screenSpacePos);
|
||||
|
||||
public override void ClearTransforms(bool propagateChildren = false, string targetMember = null)
|
||||
{
|
||||
// Consider the case of rewinding - children's transforms are handled internally, so propagating down
|
||||
// any further will cause weirdness with the Tracking bool below. Let's not propagate further at this point.
|
||||
base.ClearTransforms(false, targetMember);
|
||||
}
|
||||
|
||||
private bool tracking;
|
||||
public bool Tracking
|
||||
{
|
||||
get { return tracking; }
|
||||
private set
|
||||
{
|
||||
if (value == tracking) return;
|
||||
|
||||
if (value == tracking)
|
||||
return;
|
||||
tracking = value;
|
||||
|
||||
follow.ScaleTo(tracking ? 2.8f : 1, 300, Easing.OutQuint);
|
||||
@@ -123,8 +130,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
base.Update();
|
||||
|
||||
// Make sure to use the base version of ReceiveMouseInputAt so that we correctly check the position.
|
||||
if (Time.Current < slider.EndTime)
|
||||
Tracking = canCurrentlyTrack && lastState != null && base.ReceiveMouseInputAt(lastState.Mouse.NativeState.Position) && ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false);
|
||||
Tracking = canCurrentlyTrack
|
||||
&& lastState != null
|
||||
&& base.ReceiveMouseInputAt(lastState.Mouse.NativeState.Position)
|
||||
&& ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false);
|
||||
}
|
||||
|
||||
public void UpdateProgress(double progress, int repeat)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
@@ -61,6 +62,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
|
||||
public void SetRotation(float currentRotation)
|
||||
{
|
||||
// If we've gone back in time, it's fine to work with a fresh set of records for now
|
||||
if (records.Count > 0 && Time.Current < records.Last().Time)
|
||||
records.Clear();
|
||||
|
||||
if (records.Count > 0)
|
||||
{
|
||||
var record = records.Peek();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing;
|
||||
@@ -16,19 +17,25 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty
|
||||
private const int section_length = 400;
|
||||
private const double difficulty_multiplier = 0.0675;
|
||||
|
||||
public OsuDifficultyCalculator(Beatmap beatmap) : base(beatmap)
|
||||
public OsuDifficultyCalculator(Beatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
public OsuDifficultyCalculator(Beatmap beatmap, Mod[] mods)
|
||||
: base(beatmap, mods)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void PreprocessHitObjects()
|
||||
{
|
||||
foreach (OsuHitObject h in Objects)
|
||||
foreach (OsuHitObject h in Beatmap.HitObjects)
|
||||
(h as Slider)?.Curve?.Calculate();
|
||||
}
|
||||
|
||||
protected override double CalculateInternal(Dictionary<string, string> categoryDifficulty)
|
||||
public override double Calculate(Dictionary<string, string> categoryDifficulty = null)
|
||||
{
|
||||
OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Objects);
|
||||
OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Beatmap.HitObjects);
|
||||
Skill[] skills =
|
||||
{
|
||||
new Aim(),
|
||||
@@ -67,6 +74,6 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty
|
||||
return starRating;
|
||||
}
|
||||
|
||||
protected override BeatmapConverter<OsuHitObject> CreateBeatmapConverter() => new OsuBeatmapConverter();
|
||||
protected override BeatmapConverter<OsuHitObject> CreateBeatmapConverter(Beatmap beatmap) => new OsuBeatmapConverter();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
};
|
||||
|
||||
public override IEnumerable<BeatmapStatistic> GetBeatmapStatistics(WorkingBeatmap beatmap) => new[]
|
||||
{
|
||||
{
|
||||
new BeatmapStatistic
|
||||
{
|
||||
Name = @"Circle count",
|
||||
@@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o };
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new OsuDifficultyCalculator(beatmap);
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new OsuDifficultyCalculator(beatmap, mods);
|
||||
|
||||
public override string Description => "osu!";
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
h.Depth = depth++;
|
||||
|
||||
if (auto)
|
||||
h.State = ArmedState.Hit;
|
||||
h.State.Value = ArmedState.Hit;
|
||||
|
||||
playfieldContainer.Add(h);
|
||||
var proxyable = h as IDrawableHitObjectWithProxiedApproach;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Judgements
|
||||
{
|
||||
public class TaikoStrongHitJudgement : TaikoJudgement
|
||||
@@ -11,9 +9,7 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
||||
|
||||
public TaikoStrongHitJudgement()
|
||||
{
|
||||
base.Result = HitResult.Perfect;
|
||||
Final = true;
|
||||
}
|
||||
|
||||
public new HitResult Result => base.Result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
/// </summary>
|
||||
protected abstract TaikoAction[] HitActions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether a second hit is allowed to be processed. This occurs once this hit object has been hit successfully.
|
||||
/// </summary>
|
||||
protected bool SecondHitAllowed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the last key pressed is a valid hit key.
|
||||
/// </summary>
|
||||
@@ -45,7 +50,15 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
if (!validKeyPressed)
|
||||
AddJudgement(new TaikoJudgement { Result = HitResult.Miss });
|
||||
else if (hitOffset < HitObject.HitWindowGood)
|
||||
AddJudgement(new TaikoJudgement { Result = hitOffset < HitObject.HitWindowGreat ? HitResult.Great : HitResult.Good });
|
||||
{
|
||||
AddJudgement(new TaikoJudgement
|
||||
{
|
||||
Result = hitOffset < HitObject.HitWindowGreat ? HitResult.Great : HitResult.Good,
|
||||
Final = !HitObject.IsStrong
|
||||
});
|
||||
|
||||
SecondHitAllowed = true;
|
||||
}
|
||||
else
|
||||
AddJudgement(new TaikoJudgement { Result = HitResult.Miss });
|
||||
}
|
||||
@@ -72,7 +85,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
var offset = !AllJudged ? 0 : Time.Current - HitObject.StartTime;
|
||||
using (BeginDelayedSequence(HitObject.StartTime - Time.Current + offset, true))
|
||||
{
|
||||
switch (State)
|
||||
switch (State.Value)
|
||||
{
|
||||
case ArmedState.Idle:
|
||||
this.Delay(HitObject.HitWindowMiss).Expire();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Taiko.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
@@ -24,27 +25,25 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
{
|
||||
}
|
||||
|
||||
private bool processedSecondHit;
|
||||
public override bool AllJudged => processedSecondHit && base.AllJudged;
|
||||
|
||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||
{
|
||||
if (!base.AllJudged)
|
||||
if (!SecondHitAllowed)
|
||||
{
|
||||
base.CheckForJudgements(userTriggered, timeOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!userTriggered)
|
||||
{
|
||||
if (timeOffset > second_hit_window)
|
||||
AddJudgement(new TaikoStrongHitJudgement { Result = HitResult.Miss });
|
||||
return;
|
||||
}
|
||||
|
||||
// If we get here, we're assured that the key pressed is the correct secondary key
|
||||
|
||||
if (Math.Abs(firstHitTime - Time.Current) < second_hit_window)
|
||||
{
|
||||
AddJudgement(new TaikoStrongHitJudgement());
|
||||
processedSecondHit = true;
|
||||
}
|
||||
AddJudgement(new TaikoStrongHitJudgement { Result = HitResult.Great });
|
||||
}
|
||||
|
||||
public override bool OnReleased(TaikoAction action)
|
||||
@@ -56,8 +55,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
|
||||
public override bool OnPressed(TaikoAction action)
|
||||
{
|
||||
if (AllJudged)
|
||||
return false;
|
||||
|
||||
// Check if we've handled the first key
|
||||
if (!base.AllJudged)
|
||||
if (!SecondHitAllowed)
|
||||
{
|
||||
// First key hasn't been handled yet, attempt to handle it
|
||||
bool handled = base.OnPressed(action);
|
||||
@@ -72,10 +74,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
return handled;
|
||||
}
|
||||
|
||||
// If we've already hit the second key, don't handle this object any further
|
||||
if (processedSecondHit)
|
||||
return false;
|
||||
|
||||
// Don't handle represses of the first key
|
||||
if (firstHitAction == action)
|
||||
return false;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
/// <summary>
|
||||
/// Taiko fails at the end of the map if the player has not half-filled their HP bar.
|
||||
/// </summary>
|
||||
protected override bool FailCondition => Hits == MaxHits && Health.Value <= 0.5;
|
||||
protected override bool DefaultFailCondition => Hits == MaxHits && Health.Value <= 0.5;
|
||||
|
||||
private double hpIncreaseTick;
|
||||
private double hpIncreaseGreat;
|
||||
|
||||
@@ -36,12 +36,12 @@ namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
}
|
||||
|
||||
protected override double CalculateInternal(Dictionary<string, string> categoryDifficulty)
|
||||
public override double Calculate(Dictionary<string, string> categoryDifficulty = null)
|
||||
{
|
||||
// Fill our custom DifficultyHitObject class, that carries additional information
|
||||
difficultyHitObjects.Clear();
|
||||
|
||||
foreach (var hitObject in Objects)
|
||||
foreach (var hitObject in Beatmap.HitObjects)
|
||||
difficultyHitObjects.Add(new TaikoHitObjectDifficulty(hitObject));
|
||||
|
||||
// Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure.
|
||||
@@ -134,6 +134,6 @@ namespace osu.Game.Rulesets.Taiko
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
protected override BeatmapConverter<TaikoHitObject> CreateBeatmapConverter() => new TaikoBeatmapConverter(true);
|
||||
protected override BeatmapConverter<TaikoHitObject> CreateBeatmapConverter(Beatmap beatmap) => new TaikoBeatmapConverter(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Taiko
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o };
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new TaikoDifficultyCalculator(beatmap);
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap);
|
||||
|
||||
public override int LegacyID => 1;
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
private const double default_duration = 1000;
|
||||
private const float scroll_time = 1000;
|
||||
|
||||
public override string Description => "Taiko playfield";
|
||||
|
||||
protected override double TimePerAction => default_duration * 2;
|
||||
|
||||
private readonly Random rng = new Random(1337);
|
||||
|
||||
@@ -244,7 +244,12 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
if (judgedObject.X >= -0.05f && judgedObject is DrawableHit)
|
||||
{
|
||||
// If we're far enough away from the left stage, we should bring outselves in front of it
|
||||
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
||||
// Todo: The following try-catch is temporary for replay rewinding support
|
||||
try
|
||||
{
|
||||
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
hitExplosionContainer.Add(new HitExplosion(judgedObject, isRim));
|
||||
|
||||
@@ -5,6 +5,5 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseAllPlayers : TestCasePlayer
|
||||
{
|
||||
public override string Description => @"Showing everything to play the game.";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseBeatSyncedContainer : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Tests beat synced containers.";
|
||||
|
||||
private readonly MusicController mc;
|
||||
|
||||
public TestCaseBeatSyncedContainer()
|
||||
|
||||
@@ -9,10 +9,9 @@ using OpenTK;
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
[System.ComponentModel.Description("PlaySongSelect leaderboard/details area")]
|
||||
internal class TestCaseBeatmapDetailArea : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Beatmap details in song select";
|
||||
|
||||
public TestCaseBeatmapDetailArea()
|
||||
{
|
||||
Add(new BeatmapDetailArea
|
||||
@@ -23,4 +22,4 @@ namespace osu.Game.Tests.Visual
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
@@ -8,10 +9,9 @@ using osu.Game.Screens.Select;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[Description("PlaySongSelect beatmap details")]
|
||||
internal class TestCaseBeatmapDetails : OsuTestCase
|
||||
{
|
||||
public override string Description => "BeatmapDetails tab of BeatmapDetailArea";
|
||||
|
||||
public TestCaseBeatmapDetails()
|
||||
{
|
||||
BeatmapDetails details;
|
||||
@@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual
|
||||
StarDifficulty = 5.3f,
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual
|
||||
StarDifficulty = 4.8f,
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.ComponentModel;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Screens.Select.Options;
|
||||
using OpenTK.Graphics;
|
||||
@@ -8,10 +9,9 @@ using OpenTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[Description("bottom beatmap details")]
|
||||
internal class TestCaseBeatmapOptionsOverlay : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Beatmap options in song select";
|
||||
|
||||
public TestCaseBeatmapOptionsOverlay()
|
||||
{
|
||||
var overlay = new BeatmapOptionsOverlay();
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Overlays.BeatmapSet.Scores;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Users;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[System.ComponentModel.Description("in BeatmapOverlay")]
|
||||
public class TestCaseBeatmapScoresContainer : OsuTestCase
|
||||
{
|
||||
private readonly IEnumerable<OnlineScore> scores;
|
||||
private readonly IEnumerable<OnlineScore> anotherScores;
|
||||
private readonly OnlineScore topScore;
|
||||
private readonly Box background;
|
||||
|
||||
public TestCaseBeatmapScoresContainer()
|
||||
{
|
||||
Container container;
|
||||
ScoresContainer scoresContainer;
|
||||
|
||||
Child = container = new Container
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Width = 0.8f,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
background = new Box { RelativeSizeAxes = Axes.Both },
|
||||
scoresContainer = new ScoresContainer(),
|
||||
}
|
||||
};
|
||||
|
||||
AddStep("scores pack 1", () => scoresContainer.Scores = scores);
|
||||
AddStep("scores pack 2", () => scoresContainer.Scores = anotherScores);
|
||||
AddStep("only top score", () => scoresContainer.Scores = new[] { topScore });
|
||||
AddStep("remove scores", scoresContainer.CleanAllScores);
|
||||
AddStep("turn on loading", () => scoresContainer.IsLoading = true);
|
||||
AddStep("turn off loading", () => scoresContainer.IsLoading = false);
|
||||
AddStep("resize to big", () => container.ResizeWidthTo(1, 300));
|
||||
AddStep("resize to normal", () => container.ResizeWidthTo(0.8f, 300));
|
||||
|
||||
scores = new[]
|
||||
{
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 6602580,
|
||||
Username = @"waaiiru",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Spain",
|
||||
FlagName = @"ES",
|
||||
},
|
||||
},
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModHidden(),
|
||||
new OsuModFlashlight(),
|
||||
new OsuModHardRock(),
|
||||
},
|
||||
Rank = ScoreRank.XH,
|
||||
TotalScore = 1234567890,
|
||||
Accuracy = 1,
|
||||
},
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 4608074,
|
||||
Username = @"Skycries",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Brazil",
|
||||
FlagName = @"BR",
|
||||
},
|
||||
},
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModHidden(),
|
||||
new OsuModFlashlight(),
|
||||
},
|
||||
Rank = ScoreRank.S,
|
||||
TotalScore = 1234789,
|
||||
Accuracy = 0.9997,
|
||||
},
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 1014222,
|
||||
Username = @"eLy",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Japan",
|
||||
FlagName = @"JP",
|
||||
},
|
||||
},
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModHidden(),
|
||||
},
|
||||
Rank = ScoreRank.B,
|
||||
TotalScore = 12345678,
|
||||
Accuracy = 0.9854,
|
||||
},
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 1541390,
|
||||
Username = @"Toukai",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Canada",
|
||||
FlagName = @"CA",
|
||||
},
|
||||
},
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
},
|
||||
Rank = ScoreRank.C,
|
||||
TotalScore = 1234567,
|
||||
Accuracy = 0.8765,
|
||||
},
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 7151382,
|
||||
Username = @"Mayuri Hana",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Thailand",
|
||||
FlagName = @"TH",
|
||||
},
|
||||
},
|
||||
Rank = ScoreRank.F,
|
||||
TotalScore = 123456,
|
||||
Accuracy = 0.6543,
|
||||
},
|
||||
};
|
||||
foreach(var s in scores)
|
||||
{
|
||||
s.Statistics.Add("300", RNG.Next(2000));
|
||||
s.Statistics.Add("100", RNG.Next(2000));
|
||||
s.Statistics.Add("50", RNG.Next(2000));
|
||||
}
|
||||
|
||||
anotherScores = new[]
|
||||
{
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 4608074,
|
||||
Username = @"Skycries",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Brazil",
|
||||
FlagName = @"BR",
|
||||
},
|
||||
},
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModHidden(),
|
||||
new OsuModFlashlight(),
|
||||
},
|
||||
Rank = ScoreRank.S,
|
||||
TotalScore = 1234789,
|
||||
Accuracy = 0.9997,
|
||||
},
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 6602580,
|
||||
Username = @"waaiiru",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Spain",
|
||||
FlagName = @"ES",
|
||||
},
|
||||
},
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModHidden(),
|
||||
new OsuModFlashlight(),
|
||||
new OsuModHardRock(),
|
||||
},
|
||||
Rank = ScoreRank.XH,
|
||||
TotalScore = 1234567890,
|
||||
Accuracy = 1,
|
||||
},
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 7151382,
|
||||
Username = @"Mayuri Hana",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Thailand",
|
||||
FlagName = @"TH",
|
||||
},
|
||||
},
|
||||
Rank = ScoreRank.F,
|
||||
TotalScore = 123456,
|
||||
Accuracy = 0.6543,
|
||||
},
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 1014222,
|
||||
Username = @"eLy",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Japan",
|
||||
FlagName = @"JP",
|
||||
},
|
||||
},
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModHidden(),
|
||||
},
|
||||
Rank = ScoreRank.B,
|
||||
TotalScore = 12345678,
|
||||
Accuracy = 0.9854,
|
||||
},
|
||||
new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 1541390,
|
||||
Username = @"Toukai",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"Canada",
|
||||
FlagName = @"CA",
|
||||
},
|
||||
},
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
},
|
||||
Rank = ScoreRank.C,
|
||||
TotalScore = 1234567,
|
||||
Accuracy = 0.8765,
|
||||
},
|
||||
};
|
||||
foreach (var s in anotherScores)
|
||||
{
|
||||
s.Statistics.Add("300", RNG.Next(2000));
|
||||
s.Statistics.Add("100", RNG.Next(2000));
|
||||
s.Statistics.Add("50", RNG.Next(2000));
|
||||
}
|
||||
|
||||
topScore = new OnlineScore
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 2705430,
|
||||
Username = @"Mooha",
|
||||
Country = new Country
|
||||
{
|
||||
FullName = @"France",
|
||||
FlagName = @"FR",
|
||||
},
|
||||
},
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModFlashlight(),
|
||||
new OsuModHardRock(),
|
||||
},
|
||||
Rank = ScoreRank.B,
|
||||
TotalScore = 987654321,
|
||||
Accuracy = 0.8487,
|
||||
};
|
||||
topScore.Statistics.Add("300", RNG.Next(2000));
|
||||
topScore.Statistics.Add("100", RNG.Next(2000));
|
||||
topScore.Statistics.Add("50", RNG.Next(2000));
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
background.Colour = colours.Gray2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseBeatmapSetOverlay : OsuTestCase
|
||||
{
|
||||
public override string Description => @"view online beatmap sets";
|
||||
|
||||
private readonly BeatmapSetOverlay overlay;
|
||||
|
||||
public TestCaseBeatmapSetOverlay()
|
||||
@@ -53,6 +51,7 @@ namespace osu.Game.Tests.Visual
|
||||
Submitted = new DateTime(2016, 2, 10),
|
||||
Ranked = new DateTime(2016, 6, 19),
|
||||
BPM = 236,
|
||||
HasVideo = true,
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/415886/covers/cover.jpg?1465651778",
|
||||
@@ -75,7 +74,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 115000,
|
||||
HasVideo = false,
|
||||
CircleCount = 265,
|
||||
SliderCount = 71,
|
||||
PlayCount = 47906,
|
||||
@@ -83,7 +81,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -103,7 +101,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 118000,
|
||||
HasVideo = true,
|
||||
CircleCount = 592,
|
||||
SliderCount = 62,
|
||||
PlayCount = 162021,
|
||||
@@ -111,7 +108,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -131,7 +128,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 118000,
|
||||
HasVideo = false,
|
||||
CircleCount = 1042,
|
||||
SliderCount = 79,
|
||||
PlayCount = 225178,
|
||||
@@ -139,7 +135,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -159,7 +155,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 118000,
|
||||
HasVideo = false,
|
||||
CircleCount = 1352,
|
||||
SliderCount = 69,
|
||||
PlayCount = 131545,
|
||||
@@ -167,7 +162,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -187,7 +182,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 118000,
|
||||
HasVideo = false,
|
||||
CircleCount = 1730,
|
||||
SliderCount = 115,
|
||||
PlayCount = 117673,
|
||||
@@ -195,7 +189,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -227,6 +221,7 @@ namespace osu.Game.Tests.Visual
|
||||
Submitted = new DateTime(2016, 6, 11),
|
||||
Ranked = new DateTime(2016, 7, 12),
|
||||
BPM = 160,
|
||||
HasVideo = false,
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/625493/covers/cover.jpg?1499167472",
|
||||
@@ -249,7 +244,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 193000,
|
||||
HasVideo = false,
|
||||
CircleCount = 262,
|
||||
SliderCount = 0,
|
||||
PlayCount = 3952,
|
||||
@@ -257,7 +251,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -277,7 +271,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 193000,
|
||||
HasVideo = false,
|
||||
CircleCount = 464,
|
||||
SliderCount = 0,
|
||||
PlayCount = 4833,
|
||||
@@ -285,7 +278,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -305,7 +298,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 193000,
|
||||
HasVideo = false,
|
||||
CircleCount = 712,
|
||||
SliderCount = 0,
|
||||
PlayCount = 4405,
|
||||
@@ -313,7 +305,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -333,7 +325,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 193000,
|
||||
HasVideo = false,
|
||||
CircleCount = 943,
|
||||
SliderCount = 0,
|
||||
PlayCount = 3950,
|
||||
@@ -341,7 +332,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
@@ -361,7 +352,6 @@ namespace osu.Game.Tests.Visual
|
||||
OnlineInfo = new BeatmapOnlineInfo
|
||||
{
|
||||
Length = 193000,
|
||||
HasVideo = false,
|
||||
CircleCount = 1068,
|
||||
SliderCount = 0,
|
||||
PlayCount = 5856,
|
||||
@@ -369,7 +359,7 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
Metrics = new BeatmapMetrics
|
||||
{
|
||||
Ratings = Enumerable.Range(0, 10),
|
||||
Ratings = Enumerable.Range(0, 11),
|
||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||
},
|
||||
|
||||
@@ -8,8 +8,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseBreadcrumbs : OsuTestCase
|
||||
{
|
||||
public override string Description => @"breadcrumb > control";
|
||||
|
||||
public TestCaseBreadcrumbs()
|
||||
{
|
||||
BreadcrumbControl<BreadcrumbTab> c;
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseBreakOverlay : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Tests breaks behavior";
|
||||
|
||||
private readonly BreakOverlay breakOverlay;
|
||||
|
||||
public TestCaseBreakOverlay()
|
||||
@@ -88,4 +86,4 @@ namespace osu.Game.Tests.Visual
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Screens.Menu;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseButtonSystem : OsuTestCase
|
||||
{
|
||||
public TestCaseButtonSystem()
|
||||
{
|
||||
OsuLogo logo;
|
||||
ButtonSystem buttons;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = ColourInfo.GradientVertical(Color4.Gray, Color4.WhiteSmoke),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
buttons = new ButtonSystem(),
|
||||
logo = new OsuLogo()
|
||||
};
|
||||
|
||||
buttons.SetOsuLogo(logo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.ComponentModel;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[Description("Testing chat api and overlay")]
|
||||
internal class TestCaseChatDisplay : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Testing chat api and overlay";
|
||||
|
||||
public TestCaseChatDisplay()
|
||||
{
|
||||
Add(new ChatOverlay
|
||||
|
||||
@@ -15,8 +15,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseContextMenu : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Menu visible on right click";
|
||||
|
||||
private const int start_time = 0;
|
||||
private const int duration = 1000;
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseDialogOverlay : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Display dialogs";
|
||||
|
||||
public TestCaseDialogOverlay()
|
||||
{
|
||||
DialogOverlay overlay;
|
||||
|
||||
@@ -11,8 +11,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseDirect : OsuTestCase
|
||||
{
|
||||
public override string Description => @"osu!direct overlay";
|
||||
|
||||
private DirectOverlay direct;
|
||||
private RulesetStore rulesets;
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseDrawableRoom : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Select your favourite room";
|
||||
|
||||
private RulesetStore rulesets;
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using osu.Game.Screens.Tournament;
|
||||
using osu.Game.Screens.Tournament.Teams;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[Description("for tournament use")]
|
||||
internal class TestCaseDrawings : OsuTestCase
|
||||
{
|
||||
public override string Description => "Tournament drawings";
|
||||
|
||||
public TestCaseDrawings()
|
||||
{
|
||||
Add(new Drawings
|
||||
|
||||
@@ -7,8 +7,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseGamefield : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Showing hitobjects and what not.";
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseGraph : OsuTestCase
|
||||
{
|
||||
public override string Description => "graph";
|
||||
|
||||
public TestCaseGraph()
|
||||
{
|
||||
BarGraph graph;
|
||||
@@ -36,4 +34,4 @@ namespace osu.Game.Tests.Visual
|
||||
AddStep("Right to left", () => graph.Direction = BarDirection.RightToLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseIconButton : OsuTestCase
|
||||
{
|
||||
public override string Description => "Various display modes of icon buttons";
|
||||
|
||||
public TestCaseIconButton()
|
||||
{
|
||||
Child = new FillFlowContainer
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Screens.Menu;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseIntroSequence : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(OsuLogo),
|
||||
};
|
||||
|
||||
public TestCaseIntroSequence()
|
||||
{
|
||||
OsuLogo logo;
|
||||
|
||||
var rateAdjustClock = new StopwatchClock(true);
|
||||
var framedClock = new FramedClock(rateAdjustClock);
|
||||
framedClock.ProcessFrame();
|
||||
|
||||
Add(new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Clock = framedClock,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
logo = new OsuLogo
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AddStep(@"Restart", logo.PlayIntro);
|
||||
AddSliderStep("Playback speed", 0.0, 2.0, 1, v => rateAdjustClock.Rate = v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
private readonly KeyBindingOverlay overlay;
|
||||
|
||||
public override string Description => @"Key configuration";
|
||||
|
||||
public TestCaseKeyConfiguration()
|
||||
{
|
||||
Child = overlay = new KeyBindingOverlay();
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseKeyCounter : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Tests key counter";
|
||||
|
||||
public TestCaseKeyCounter()
|
||||
{
|
||||
KeyCounterCollection kc = new KeyCounterCollection
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.ComponentModel;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
@@ -9,10 +10,9 @@ using OpenTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[Description("PlaySongSelect leaderboard")]
|
||||
internal class TestCaseLeaderboard : OsuTestCase
|
||||
{
|
||||
public override string Description => @"From song select";
|
||||
|
||||
private readonly Leaderboard leaderboard;
|
||||
|
||||
private void newScores()
|
||||
|
||||
@@ -11,8 +11,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseMedalOverlay : OsuTestCase
|
||||
{
|
||||
public override string Description => @"medal get!";
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(MedalOverlay),
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Screens.Menu;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseMenuButtonSystem : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Main menu button system";
|
||||
|
||||
public TestCaseMenuButtonSystem()
|
||||
{
|
||||
Add(new Box
|
||||
{
|
||||
Colour = ColourInfo.GradientVertical(Color4.Gray, Color4.WhiteSmoke),
|
||||
RelativeSizeAxes = Framework.Graphics.Axes.Both,
|
||||
});
|
||||
Add(new ButtonSystem());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.ComponentModel;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[Description("player pause/fail screens")]
|
||||
internal class TestCaseMenuOverlays : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Tests pause and fail overlays";
|
||||
|
||||
public TestCaseMenuOverlays()
|
||||
{
|
||||
FailOverlay failOverlay;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.ComponentModel;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Overlays.Mods;
|
||||
@@ -10,10 +11,9 @@ using OpenTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[Description("mod select and icon display")]
|
||||
internal class TestCaseMods : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Mod select overlay and in-game display";
|
||||
|
||||
private ModSelectOverlay modSelect;
|
||||
private ModDisplay modDisplay;
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseMusicController : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Tests music controller ui.";
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public TestCaseMusicController()
|
||||
|
||||
@@ -15,8 +15,6 @@ namespace osu.Game.Tests.Visual
|
||||
[TestFixture]
|
||||
internal class TestCaseNotificationOverlay : OsuTestCase
|
||||
{
|
||||
public override string Description => @"I handle notifications";
|
||||
|
||||
private readonly NotificationOverlay manager;
|
||||
|
||||
public TestCaseNotificationOverlay()
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace osu.Game.Tests.Visual
|
||||
private FrameworkConfigManager config;
|
||||
private Bindable<FrameSync> frameSyncMode;
|
||||
|
||||
public override string Description => @"Make it easier to see setting changes";
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Menu;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseOsuGame : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(OsuLogo),
|
||||
};
|
||||
|
||||
public TestCaseOsuGame()
|
||||
{
|
||||
var rateAdjustClock = new StopwatchClock(true);
|
||||
var framedClock = new FramedClock(rateAdjustClock);
|
||||
framedClock.ProcessFrame();
|
||||
|
||||
Add(new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
});
|
||||
|
||||
Add(new Loader());
|
||||
|
||||
AddSliderStep("Playback speed", 0.0, 2.0, 1, v => rateAdjustClock.Rate = v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,11 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
@@ -19,8 +22,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
private BeatmapManager manager;
|
||||
|
||||
public override string Description => @"with fake data";
|
||||
|
||||
private RulesetStore rulesets;
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
@@ -61,7 +62,7 @@ namespace osu.Game.Tests.Visual
|
||||
return new BeatmapSetInfo
|
||||
{
|
||||
OnlineBeatmapSetID = 1234 + i,
|
||||
Hash = "d8e8fca2dc0f896fd7cb4cb0031ba249",
|
||||
Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
OnlineBeatmapSetID = 1234 + i,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Edit.Components;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCasePlaybackControl : OsuTestCase
|
||||
{
|
||||
public TestCasePlaybackControl()
|
||||
{
|
||||
var playback = new PlaybackControl
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(200,100)
|
||||
};
|
||||
playback.Beatmap.Value = new TestWorkingBeatmap(new Beatmap());
|
||||
|
||||
Add(playback);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseReplay : TestCasePlayer
|
||||
{
|
||||
public override string Description => @"Testing replay playback.";
|
||||
|
||||
protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset)
|
||||
{
|
||||
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
||||
|
||||
@@ -3,15 +3,13 @@
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.ReplaySettings;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseReplaySettingsOverlay : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Settings visible in replay/auto";
|
||||
|
||||
public TestCaseReplaySettingsOverlay()
|
||||
{
|
||||
ExampleContainer container;
|
||||
@@ -24,7 +22,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
Add(container = new ExampleContainer());
|
||||
|
||||
AddStep(@"Add button", () => container.Add(new OsuButton
|
||||
AddStep(@"Add button", () => container.Add(new TriangleButton
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Text = @"Button",
|
||||
|
||||
@@ -15,8 +15,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
private BeatmapManager beatmaps;
|
||||
|
||||
public override string Description => @"Results after playing.";
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(BeatmapManager beatmaps)
|
||||
{
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseRoomInspector : OsuTestCase
|
||||
{
|
||||
public override string Description => @"from the multiplayer lobby";
|
||||
|
||||
private RulesetStore rulesets;
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseScoreCounter : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Tests multiple counters";
|
||||
|
||||
public TestCaseScoreCounter()
|
||||
{
|
||||
int numerator = 0, denominator = 0;
|
||||
|
||||
@@ -7,8 +7,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseSettings : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Tests the settings overlay";
|
||||
|
||||
private readonly SettingsOverlay settings;
|
||||
|
||||
public TestCaseSettings()
|
||||
|
||||
@@ -7,8 +7,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseSkipButton : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Skip skip skippediskip";
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
@@ -8,8 +8,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseSocial : OsuTestCase
|
||||
{
|
||||
public override string Description => @"social browser overlay";
|
||||
|
||||
public TestCaseSocial()
|
||||
{
|
||||
SocialOverlay s = new SocialOverlay
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseSongProgress : OsuTestCase
|
||||
{
|
||||
public override string Description => @"With fake data";
|
||||
|
||||
private readonly SongProgress progress;
|
||||
private readonly SongProgressGraph graph;
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseStoryboard : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Tests storyboards.";
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly Container<DrawableStoryboard> storyboardContainer;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.ComponentModel;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
@@ -9,10 +10,9 @@ using OpenTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[Description("SongSelect filter control")]
|
||||
public class TestCaseTabControl : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Filter for song select";
|
||||
|
||||
public TestCaseTabControl()
|
||||
{
|
||||
OsuSpriteText text;
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseTextAwesome : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Tests display of icons";
|
||||
|
||||
public TestCaseTextAwesome()
|
||||
{
|
||||
FillFlowContainer flow;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.ComponentModel;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[Description("mostly back button")]
|
||||
internal class TestCaseTwoLayerButton : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Mostly back button";
|
||||
|
||||
public TestCaseTwoLayerButton()
|
||||
{
|
||||
Add(new BackButton());
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseUserPanel : OsuTestCase
|
||||
{
|
||||
public override string Description => @"Panels for displaying a user's status";
|
||||
|
||||
public TestCaseUserPanel()
|
||||
{
|
||||
UserPanel flyte;
|
||||
@@ -36,7 +34,8 @@ namespace osu.Game.Tests.Visual
|
||||
Username = @"peppy",
|
||||
Id = 2,
|
||||
Country = new Country { FlagName = @"AU" },
|
||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg"
|
||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
||||
IsSupporter = true,
|
||||
}) { Width = 300 },
|
||||
},
|
||||
});
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseUserProfile : OsuTestCase
|
||||
{
|
||||
public override string Description => "Tests user's profile page.";
|
||||
|
||||
public TestCaseUserProfile()
|
||||
{
|
||||
var profile = new UserProfileOverlay();
|
||||
|
||||
@@ -15,8 +15,6 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseUserRanks : OsuTestCase
|
||||
{
|
||||
public override string Description => "showing your latest achievements";
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(DrawableScore), typeof(RanksSection) };
|
||||
|
||||
public TestCaseUserRanks()
|
||||
@@ -41,7 +39,7 @@ namespace osu.Game.Tests.Visual
|
||||
}
|
||||
});
|
||||
|
||||
AddStep("Show cookiezi", () => ranks.User = new User { Id = 124493 });
|
||||
AddStep("Show cookiezi", () => ranks.User.Value = new User { Id = 124493 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
<Compile Include="Visual\TestCaseBeatmapDetailArea.cs" />
|
||||
<Compile Include="Visual\TestCaseBeatmapDetails.cs" />
|
||||
<Compile Include="Visual\TestCaseBeatmapOptionsOverlay.cs" />
|
||||
<Compile Include="Visual\TestCaseBeatmapScoresContainer.cs" />
|
||||
<Compile Include="Visual\TestCaseBeatmapSetOverlay.cs" />
|
||||
<Compile Include="Visual\TestCaseBeatSyncedContainer.cs" />
|
||||
<Compile Include="Visual\TestCaseBreadcrumbs.cs" />
|
||||
@@ -110,17 +111,20 @@
|
||||
<Compile Include="Visual\TestCaseGamefield.cs" />
|
||||
<Compile Include="Visual\TestCaseGraph.cs" />
|
||||
<Compile Include="Visual\TestCaseIconButton.cs" />
|
||||
<Compile Include="Visual\TestCaseIntroSequence.cs" />
|
||||
<Compile Include="Visual\TestCaseKeyConfiguration.cs" />
|
||||
<Compile Include="Visual\TestCaseKeyCounter.cs" />
|
||||
<Compile Include="Visual\TestCaseLeaderboard.cs" />
|
||||
<Compile Include="Visual\TestCaseMedalOverlay.cs" />
|
||||
<Compile Include="Visual\TestCaseMenuButtonSystem.cs" />
|
||||
<Compile Include="Visual\TestCaseButtonSystem.cs" />
|
||||
<Compile Include="Visual\TestCaseMenuOverlays.cs" />
|
||||
<Compile Include="Visual\TestCaseMods.cs" />
|
||||
<Compile Include="Visual\TestCaseMusicController.cs" />
|
||||
<Compile Include="Visual\TestCaseNotificationOverlay.cs" />
|
||||
<Compile Include="Visual\TestCaseOnScreenDisplay.cs" />
|
||||
<Compile Include="Visual\TestCaseAllPlayers.cs" />
|
||||
<Compile Include="Visual\TestCaseOsuGame.cs" />
|
||||
<Compile Include="Visual\TestCasePlaybackControl.cs" />
|
||||
<Compile Include="Visual\TestCasePlaySongSelect.cs" />
|
||||
<Compile Include="Visual\TestCaseReplay.cs" />
|
||||
<Compile Include="Visual\TestCaseReplaySettingsOverlay.cs" />
|
||||
|
||||
@@ -6,12 +6,13 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.IO.Serialization;
|
||||
using osu.Game.Rulesets;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
public class BeatmapInfo : IEquatable<BeatmapInfo>, IJsonSerializable
|
||||
public class BeatmapInfo : IEquatable<BeatmapInfo>, IJsonSerializable, IHasPrimaryKey
|
||||
{
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int ID { get; set; }
|
||||
@@ -19,12 +20,23 @@ namespace osu.Game.Beatmaps
|
||||
//TODO: should be in database
|
||||
public int BeatmapVersion;
|
||||
|
||||
private int? onlineBeatmapID;
|
||||
private int? onlineBeatmapSetID;
|
||||
|
||||
[JsonProperty("id")]
|
||||
public int? OnlineBeatmapID { get; set; }
|
||||
public int? OnlineBeatmapID
|
||||
{
|
||||
get { return onlineBeatmapID; }
|
||||
set { onlineBeatmapID = value > 0 ? value : null; }
|
||||
}
|
||||
|
||||
[JsonProperty("beatmapset_id")]
|
||||
[NotMapped]
|
||||
public int? OnlineBeatmapSetID { get; set; }
|
||||
public int? OnlineBeatmapSetID
|
||||
{
|
||||
get { return onlineBeatmapSetID; }
|
||||
set { onlineBeatmapSetID = value > 0 ? value : null; }
|
||||
}
|
||||
|
||||
public int BeatmapSetInfoID { get; set; }
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Ionic.Zip;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -17,6 +18,7 @@ using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.Beatmaps.IO;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.IPC;
|
||||
using osu.Game.Online.API;
|
||||
@@ -51,6 +53,11 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
public event Action<BeatmapInfo> BeatmapRestored;
|
||||
|
||||
/// <summary>
|
||||
/// Fired when a beatmap download begins.
|
||||
/// </summary>
|
||||
public event Action<DownloadBeatmapSetRequest> BeatmapDownloadBegan;
|
||||
|
||||
/// <summary>
|
||||
/// A default representation of a WorkingBeatmap to use when no beatmap is available.
|
||||
/// </summary>
|
||||
@@ -164,7 +171,7 @@ namespace osu.Game.Beatmaps
|
||||
catch (Exception e)
|
||||
{
|
||||
e = e.InnerException ?? e;
|
||||
Logger.Error(e, @"Could not import beatmap set");
|
||||
Logger.Error(e, $@"Could not import beatmap set ({Path.GetFileName(path)})");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,21 +227,29 @@ namespace osu.Game.Beatmaps
|
||||
/// Downloads a beatmap.
|
||||
/// </summary>
|
||||
/// <param name="beatmapSetInfo">The <see cref="BeatmapSetInfo"/> to be downloaded.</param>
|
||||
/// <returns>A new <see cref="DownloadBeatmapSetRequest"/>, or an existing one if a download is already in progress.</returns>
|
||||
public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo)
|
||||
/// <param name="noVideo">Whether the beatmap should be downloaded without video. Defaults to false.</param>
|
||||
public void Download(BeatmapSetInfo beatmapSetInfo, bool noVideo = false)
|
||||
{
|
||||
var existing = GetExistingDownload(beatmapSetInfo);
|
||||
|
||||
if (existing != null) return existing;
|
||||
if (existing != null || api == null) return;
|
||||
|
||||
if (api == null) return null;
|
||||
if (!api.LocalUser.Value.IsSupporter)
|
||||
{
|
||||
PostNotification?.Invoke(new SimpleNotification
|
||||
{
|
||||
Icon = FontAwesome.fa_superpowers,
|
||||
Text = "You gotta be a supporter to download for now 'yo"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
ProgressNotification downloadNotification = new ProgressNotification
|
||||
{
|
||||
Text = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}",
|
||||
};
|
||||
|
||||
var request = new DownloadBeatmapSetRequest(beatmapSetInfo);
|
||||
var request = new DownloadBeatmapSetRequest(beatmapSetInfo, noVideo);
|
||||
|
||||
request.DownloadProgressed += progress =>
|
||||
{
|
||||
@@ -244,11 +259,17 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
request.Success += data =>
|
||||
{
|
||||
downloadNotification.State = ProgressNotificationState.Completed;
|
||||
downloadNotification.Text = $"Importing {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}";
|
||||
|
||||
using (var stream = new MemoryStream(data))
|
||||
using (var archive = new OszArchiveReader(stream))
|
||||
Import(archive);
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
// This gets scheduled back to the update thread, but we want the import to run in the background.
|
||||
using (var stream = new MemoryStream(data))
|
||||
using (var archive = new OszArchiveReader(stream))
|
||||
Import(archive);
|
||||
|
||||
downloadNotification.State = ProgressNotificationState.Completed;
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
|
||||
currentDownloads.Remove(request);
|
||||
};
|
||||
@@ -272,9 +293,8 @@ namespace osu.Game.Beatmaps
|
||||
PostNotification?.Invoke(downloadNotification);
|
||||
|
||||
// don't run in the main api queue as this is a long-running task.
|
||||
Task.Run(() => request.Perform(api));
|
||||
|
||||
return request;
|
||||
Task.Factory.StartNew(() => request.Perform(api), TaskCreationOptions.LongRunning);
|
||||
BeatmapDownloadBegan?.Invoke(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -334,6 +354,8 @@ namespace osu.Game.Beatmaps
|
||||
/// Returns a <see cref="BeatmapSetInfo"/> to a usable state if it has previously been deleted but not yet purged.
|
||||
/// Is a no-op for already usable beatmaps.
|
||||
/// </summary>
|
||||
/// <param name="beatmaps">The store to restore beatmaps from.</param>
|
||||
/// <param name="files">The store to restore beatmap files from.</param>
|
||||
/// <param name="beatmapSet">The beatmap to restore.</param>
|
||||
private void undelete(BeatmapStore beatmaps, FileStore files, BeatmapSetInfo beatmapSet)
|
||||
{
|
||||
@@ -372,7 +394,7 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
||||
public BeatmapSetInfo QueryBeatmapSet(Func<BeatmapSetInfo, bool> query) => beatmaps.BeatmapSets.FirstOrDefault(query);
|
||||
public BeatmapSetInfo QueryBeatmapSet(Expression<Func<BeatmapSetInfo, bool>> query) => beatmaps.BeatmapSets.AsNoTracking().FirstOrDefault(query);
|
||||
|
||||
/// <summary>
|
||||
/// Refresh an existing instance of a <see cref="BeatmapSetInfo"/> from the store.
|
||||
@@ -386,21 +408,21 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>Results from the provided query.</returns>
|
||||
public List<BeatmapSetInfo> QueryBeatmapSets(Func<BeatmapSetInfo, bool> query) => beatmaps.BeatmapSets.Where(query).ToList();
|
||||
public IEnumerable<BeatmapSetInfo> QueryBeatmapSets(Expression<Func<BeatmapSetInfo, bool>> query) => beatmaps.BeatmapSets.AsNoTracking().Where(query);
|
||||
|
||||
/// <summary>
|
||||
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
||||
public BeatmapInfo QueryBeatmap(Func<BeatmapInfo, bool> query) => beatmaps.Beatmaps.FirstOrDefault(query);
|
||||
public BeatmapInfo QueryBeatmap(Expression<Func<BeatmapInfo, bool>> query) => beatmaps.Beatmaps.AsNoTracking().FirstOrDefault(query);
|
||||
|
||||
/// <summary>
|
||||
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>Results from the provided query.</returns>
|
||||
public List<BeatmapInfo> QueryBeatmaps(Func<BeatmapInfo, bool> query) => beatmaps.Beatmaps.Where(query).ToList();
|
||||
public IEnumerable<BeatmapInfo> QueryBeatmaps(Expression<Func<BeatmapInfo, bool>> query) => beatmaps.Beatmaps.AsNoTracking().Where(query);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ArchiveReader"/> from a valid storage path.
|
||||
@@ -419,6 +441,8 @@ namespace osu.Game.Beatmaps
|
||||
/// Import a beamap into our local <see cref="FileStore"/> storage.
|
||||
/// If the beatmap is already imported, the existing instance will be returned.
|
||||
/// </summary>
|
||||
/// <param name="files">The store to import beatmap files to.</param>
|
||||
/// <param name="beatmaps">The store to import beatmaps to.</param>
|
||||
/// <param name="reader">The beatmap archive to be read.</param>
|
||||
/// <returns>The imported beatmap, or an existing instance if it is already present.</returns>
|
||||
private BeatmapSetInfo importToStorage(FileStore files, BeatmapStore beatmaps, ArchiveReader reader)
|
||||
@@ -472,7 +496,8 @@ namespace osu.Game.Beatmaps
|
||||
using (var stream = new StreamReader(reader.GetStream(mapName)))
|
||||
metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
|
||||
|
||||
beatmapSet = new BeatmapSetInfo
|
||||
// check if a set already exists with the same online id.
|
||||
beatmapSet = beatmaps.BeatmapSets.FirstOrDefault(b => b.OnlineBeatmapSetID == metadata.OnlineBeatmapSetID) ?? new BeatmapSetInfo
|
||||
{
|
||||
OnlineBeatmapSetID = metadata.OnlineBeatmapSetID,
|
||||
Beatmaps = new List<BeatmapInfo>(),
|
||||
@@ -499,16 +524,21 @@ namespace osu.Game.Beatmaps
|
||||
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
||||
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();
|
||||
|
||||
// TODO: Diff beatmap metadata with set metadata and leave it here if necessary
|
||||
beatmap.BeatmapInfo.Metadata = null;
|
||||
var existing = beatmaps.Beatmaps.FirstOrDefault(b => b.Hash == beatmap.BeatmapInfo.Hash || b.OnlineBeatmapID == beatmap.BeatmapInfo.OnlineBeatmapID);
|
||||
|
||||
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
||||
if (existing == null)
|
||||
{
|
||||
// TODO: Diff beatmap metadata with set metadata and leave it here if necessary
|
||||
beatmap.BeatmapInfo.Metadata = null;
|
||||
|
||||
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
||||
beatmap.BeatmapInfo.Ruleset = ruleset;
|
||||
beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance()?.CreateDifficultyCalculator(beatmap).Calculate() ?? 0;
|
||||
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
||||
|
||||
beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo);
|
||||
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
||||
beatmap.BeatmapInfo.Ruleset = ruleset;
|
||||
beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance()?.CreateDifficultyCalculator(beatmap).Calculate() ?? 0;
|
||||
|
||||
beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,15 @@ namespace osu.Game.Beatmaps
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int ID { get; set; }
|
||||
|
||||
private int? onlineBeatmapSetID;
|
||||
|
||||
[NotMapped]
|
||||
public int? OnlineBeatmapSetID { get; set; }
|
||||
[JsonProperty(@"id")]
|
||||
public int? OnlineBeatmapSetID
|
||||
{
|
||||
get { return onlineBeatmapSetID; }
|
||||
set { onlineBeatmapSetID = value > 0 ? value : null; }
|
||||
}
|
||||
|
||||
public string Title { get; set; }
|
||||
public string TitleUnicode { get; set; }
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace osu.Game.Beatmaps
|
||||
public class BeatmapMetrics
|
||||
{
|
||||
/// <summary>
|
||||
/// Total vote counts of user ratings on a scale of 0..length.
|
||||
/// Total vote counts of user ratings on a scale of 0..10 where 0 is unused (probably will be fixed at API?).
|
||||
/// </summary>
|
||||
public IEnumerable<int> Ratings { get; set; }
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
/// <summary>
|
||||
@@ -15,33 +13,24 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
public double Length { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this beatmap has a background video.
|
||||
/// </summary>
|
||||
public bool HasVideo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of circles in this beatmap.
|
||||
/// </summary>
|
||||
[JsonProperty(@"count_circles")]
|
||||
public int CircleCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of sliders in this beatmap.
|
||||
/// </summary>
|
||||
[JsonProperty(@"count_sliders")]
|
||||
public int SliderCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of plays this beatmap has.
|
||||
/// </summary>
|
||||
[JsonProperty(@"playcount")]
|
||||
public int PlayCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of passes this beatmap has.
|
||||
/// </summary>
|
||||
[JsonProperty(@"passcount")]
|
||||
public int PassCount { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
public class BeatmapSetInfo
|
||||
public class BeatmapSetInfo : IHasPrimaryKey
|
||||
{
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int ID { get; set; }
|
||||
|
||||
@@ -26,16 +26,19 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
public DateTimeOffset? LastUpdated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this beatmap set has a background video.
|
||||
/// </summary>
|
||||
public bool HasVideo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The different sizes of cover art for this beatmap set.
|
||||
/// </summary>
|
||||
[JsonProperty(@"covers")]
|
||||
public BeatmapSetOnlineCovers Covers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A small sample clip of this beatmap set's song.
|
||||
/// </summary>
|
||||
[JsonProperty(@"previewUrl")]
|
||||
public string Preview { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -46,13 +49,11 @@ namespace osu.Game.Beatmaps
|
||||
/// <summary>
|
||||
/// The amount of plays this beatmap set has.
|
||||
/// </summary>
|
||||
[JsonProperty(@"play_count")]
|
||||
public int PlayCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of people who have favourited this beatmap set.
|
||||
/// </summary>
|
||||
[JsonProperty(@"favourite_count")]
|
||||
public int FavouriteCount { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using osu.Game.Database;
|
||||
@@ -25,21 +24,6 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Prepare(bool reset = false)
|
||||
{
|
||||
if (reset)
|
||||
{
|
||||
var context = GetContext();
|
||||
|
||||
// https://stackoverflow.com/a/10450893
|
||||
context.Database.ExecuteSqlCommand("DELETE FROM BeatmapMetadata");
|
||||
context.Database.ExecuteSqlCommand("DELETE FROM BeatmapDifficulty");
|
||||
context.Database.ExecuteSqlCommand("DELETE FROM BeatmapSetInfo");
|
||||
context.Database.ExecuteSqlCommand("DELETE FROM BeatmapSetFileInfo");
|
||||
context.Database.ExecuteSqlCommand("DELETE FROM BeatmapInfo");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a <see cref="BeatmapSetInfo"/> to the database.
|
||||
/// </summary>
|
||||
@@ -63,10 +47,10 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
var context = GetContext();
|
||||
|
||||
if (beatmapSet.DeletePending) return false;
|
||||
Refresh(ref beatmapSet, BeatmapSets);
|
||||
|
||||
if (beatmapSet.DeletePending) return false;
|
||||
beatmapSet.DeletePending = true;
|
||||
context.Update(beatmapSet);
|
||||
context.SaveChanges();
|
||||
|
||||
BeatmapSetRemoved?.Invoke(beatmapSet);
|
||||
@@ -82,10 +66,10 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
var context = GetContext();
|
||||
|
||||
if (!beatmapSet.DeletePending) return false;
|
||||
Refresh(ref beatmapSet, BeatmapSets);
|
||||
|
||||
if (!beatmapSet.DeletePending) return false;
|
||||
beatmapSet.DeletePending = false;
|
||||
context.Update(beatmapSet);
|
||||
context.SaveChanges();
|
||||
|
||||
BeatmapSetAdded?.Invoke(beatmapSet);
|
||||
@@ -101,10 +85,10 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
var context = GetContext();
|
||||
|
||||
if (beatmap.Hidden) return false;
|
||||
Refresh(ref beatmap, Beatmaps);
|
||||
|
||||
if (beatmap.Hidden) return false;
|
||||
beatmap.Hidden = true;
|
||||
context.Update(beatmap);
|
||||
context.SaveChanges();
|
||||
|
||||
BeatmapHidden?.Invoke(beatmap);
|
||||
@@ -120,10 +104,10 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
var context = GetContext();
|
||||
|
||||
if (!beatmap.Hidden) return false;
|
||||
Refresh(ref beatmap, Beatmaps);
|
||||
|
||||
if (!beatmap.Hidden) return false;
|
||||
beatmap.Hidden = false;
|
||||
context.Update(beatmap);
|
||||
context.SaveChanges();
|
||||
|
||||
BeatmapRestored?.Invoke(beatmap);
|
||||
@@ -151,17 +135,17 @@ namespace osu.Game.Beatmaps
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
public IEnumerable<BeatmapSetInfo> BeatmapSets => GetContext().BeatmapSetInfo
|
||||
.Include(s => s.Metadata)
|
||||
.Include(s => s.Beatmaps).ThenInclude(s => s.Ruleset)
|
||||
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
|
||||
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
|
||||
.Include(s => s.Files).ThenInclude(f => f.FileInfo);
|
||||
public IQueryable<BeatmapSetInfo> BeatmapSets => GetContext().BeatmapSetInfo
|
||||
.Include(s => s.Metadata)
|
||||
.Include(s => s.Beatmaps).ThenInclude(s => s.Ruleset)
|
||||
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
|
||||
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
|
||||
.Include(s => s.Files).ThenInclude(f => f.FileInfo);
|
||||
|
||||
public IEnumerable<BeatmapInfo> Beatmaps => GetContext().BeatmapInfo
|
||||
.Include(b => b.BeatmapSet).ThenInclude(s => s.Metadata)
|
||||
.Include(b => b.Metadata)
|
||||
.Include(b => b.Ruleset)
|
||||
.Include(b => b.BaseDifficulty);
|
||||
public IQueryable<BeatmapInfo> Beatmaps => GetContext().BeatmapInfo
|
||||
.Include(b => b.BeatmapSet).ThenInclude(s => s.Metadata)
|
||||
.Include(b => b.Metadata)
|
||||
.Include(b => b.Ruleset)
|
||||
.Include(b => b.BaseDifficulty);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Lists;
|
||||
@@ -85,6 +86,9 @@ namespace osu.Game.Beatmaps.ControlPoints
|
||||
private T binarySearch<T>(SortedList<T> list, double time, T prePoint = null)
|
||||
where T : ControlPoint, new()
|
||||
{
|
||||
if (list == null)
|
||||
throw new ArgumentNullException(nameof(list));
|
||||
|
||||
if (list.Count == 0)
|
||||
return new T();
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Framework.Timing;
|
||||
using System.Linq;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
@@ -10,45 +14,46 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
protected double TimeRate = 1;
|
||||
|
||||
protected abstract double CalculateInternal(Dictionary<string, string> categoryDifficulty);
|
||||
|
||||
private void loadTiming()
|
||||
{
|
||||
// TODO: Handle mods
|
||||
const int audio_rate = 100;
|
||||
TimeRate = audio_rate / 100.0;
|
||||
}
|
||||
|
||||
public double Calculate(Dictionary<string, string> categoryDifficulty = null)
|
||||
{
|
||||
loadTiming();
|
||||
double difficulty = CalculateInternal(categoryDifficulty);
|
||||
return difficulty;
|
||||
}
|
||||
public abstract double Calculate(Dictionary<string, string> categoryDifficulty = null);
|
||||
}
|
||||
|
||||
public abstract class DifficultyCalculator<T> : DifficultyCalculator where T : HitObject
|
||||
{
|
||||
protected readonly Beatmap Beatmap;
|
||||
protected readonly Beatmap<T> Beatmap;
|
||||
protected readonly Mod[] Mods;
|
||||
|
||||
protected List<T> Objects;
|
||||
|
||||
protected DifficultyCalculator(Beatmap beatmap)
|
||||
protected DifficultyCalculator(Beatmap beatmap, Mod[] mods = null)
|
||||
{
|
||||
Beatmap = beatmap;
|
||||
Beatmap = CreateBeatmapConverter(beatmap).Convert(beatmap);
|
||||
Mods = mods ?? new Mod[0];
|
||||
|
||||
Objects = CreateBeatmapConverter().Convert(beatmap).HitObjects;
|
||||
|
||||
foreach (var h in Objects)
|
||||
h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
|
||||
ApplyMods(Mods);
|
||||
|
||||
PreprocessHitObjects();
|
||||
}
|
||||
|
||||
protected virtual void ApplyMods(Mod[] mods)
|
||||
{
|
||||
var clock = new StopwatchClock();
|
||||
mods.OfType<IApplicableToClock>().ForEach(m => m.ApplyToClock(clock));
|
||||
TimeRate = clock.Rate;
|
||||
|
||||
foreach (var mod in Mods.OfType<IApplicableToDifficulty>())
|
||||
mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToHitObject<T>>())
|
||||
foreach (var obj in Beatmap.HitObjects)
|
||||
mod.ApplyToHitObject(obj);
|
||||
|
||||
foreach (var h in Beatmap.HitObjects)
|
||||
h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
}
|
||||
|
||||
protected virtual void PreprocessHitObjects()
|
||||
{
|
||||
}
|
||||
|
||||
protected abstract BeatmapConverter<T> CreateBeatmapConverter();
|
||||
protected abstract BeatmapConverter<T> CreateBeatmapConverter(Beatmap beatmap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
internal class BeatmapBackgroundSprite : Sprite
|
||||
public class BeatmapBackgroundSprite : Sprite
|
||||
{
|
||||
private readonly WorkingBeatmap working;
|
||||
|
||||
public BeatmapBackgroundSprite(WorkingBeatmap working)
|
||||
{
|
||||
if (working == null)
|
||||
throw new ArgumentNullException(nameof(working));
|
||||
|
||||
this.working = working;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,11 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
|
||||
public BeatmapGroup(BeatmapSetInfo beatmapSet, BeatmapManager manager)
|
||||
{
|
||||
if (beatmapSet == null)
|
||||
throw new ArgumentNullException(nameof(beatmapSet));
|
||||
if (manager == null)
|
||||
throw new ArgumentNullException(nameof(manager));
|
||||
|
||||
BeatmapSet = beatmapSet;
|
||||
WorkingBeatmap beatmap = manager.GetWorkingBeatmap(BeatmapSet.Beatmaps.FirstOrDefault());
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user