mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 23:12:56 +08:00
Merge remote-tracking branch 'upstream/master' into lighten-playfield-during-breaks
This commit is contained in:
commit
7559012fb7
@ -54,6 +54,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.1210.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.1212.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
drawableRuleset = new DrawableCatchRuleset(new CatchRuleset(), beatmap, Array.Empty<Mod>())
|
||||
drawableRuleset = new DrawableCatchRuleset(new CatchRuleset(), beatmap.GetPlayableBeatmap(new CatchRuleset().RulesetInfo))
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
public class CatchRuleset : Ruleset
|
||||
{
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableCatchRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableCatchRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
|
||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
|
||||
|
||||
|
@ -2,23 +2,21 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Scoring
|
||||
{
|
||||
public class CatchScoreProcessor : ScoreProcessor<CatchHitObject>
|
||||
public class CatchScoreProcessor : ScoreProcessor
|
||||
{
|
||||
public CatchScoreProcessor(DrawableRuleset<CatchHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
public CatchScoreProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
private float hpDrainRate;
|
||||
|
||||
protected override void ApplyBeatmap(Beatmap<CatchHitObject> beatmap)
|
||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
base.ApplyBeatmap(beatmap);
|
||||
|
||||
|
@ -25,14 +25,14 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
protected override bool UserScrollSpeedAdjustment => false;
|
||||
|
||||
public DrawableCatchRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableCatchRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
Direction.Value = ScrollingDirection.Down;
|
||||
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.Beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
|
||||
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
|
||||
}
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(Beatmap);
|
||||
|
||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
public new IScrollingInfo ScrollingInfo => base.ScrollingInfo;
|
||||
|
||||
public DrawableManiaEditRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableManiaEditRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
|
||||
public int TotalColumns => ((ManiaPlayfield)drawableRuleset.Playfield).TotalColumns;
|
||||
|
||||
protected override DrawableRuleset<ManiaHitObject> CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
protected override DrawableRuleset<ManiaHitObject> CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
{
|
||||
drawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods);
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
public class ManiaRuleset : Ruleset
|
||||
{
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableManiaRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableManiaRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
|
||||
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score);
|
||||
|
||||
|
@ -3,13 +3,11 @@
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Scoring
|
||||
{
|
||||
internal class ManiaScoreProcessor : ScoreProcessor<ManiaHitObject>
|
||||
internal class ManiaScoreProcessor : ScoreProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// The hit HP multiplier at OD = 0.
|
||||
@ -51,12 +49,12 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
/// </summary>
|
||||
private double hpMultiplier = 1;
|
||||
|
||||
public ManiaScoreProcessor(DrawableRuleset<ManiaHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
public ManiaScoreProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ApplyBeatmap(Beatmap<ManiaHitObject> beatmap)
|
||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
base.ApplyBeatmap(beatmap);
|
||||
|
||||
@ -65,7 +63,7 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
hpMissMultiplier = BeatmapDifficulty.DifficultyRange(difficulty.DrainRate, hp_multiplier_miss_min, hp_multiplier_miss_mid, hp_multiplier_miss_max);
|
||||
}
|
||||
|
||||
protected override void SimulateAutoplay(Beatmap<ManiaHitObject> beatmap)
|
||||
protected override void SimulateAutoplay(IBeatmap beatmap)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
private readonly Bindable<ManiaScrollingDirection> configDirection = new Bindable<ManiaScrollingDirection>();
|
||||
|
||||
public DrawableManiaRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableManiaRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
BarLines = new BarLineGenerator<BarLine>(Beatmap).BarLines;
|
||||
@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages);
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(Beatmap);
|
||||
|
||||
public override int Variant => (int)(Beatmap.Stages.Count == 1 ? PlayfieldType.Single : PlayfieldType.Dual) + Beatmap.TotalColumns;
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
/// </summary>
|
||||
private const double editor_hit_object_fade_out_extension = 500;
|
||||
|
||||
public DrawableOsuEditRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableOsuEditRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
}
|
||||
|
||||
protected override DrawableRuleset<OsuHitObject> CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
protected override DrawableRuleset<OsuHitObject> CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
=> new DrawableOsuEditRuleset(ruleset, beatmap, mods);
|
||||
|
||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
{
|
||||
public class OsuRuleset : Ruleset
|
||||
{
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableOsuRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableOsuRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap);
|
||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap);
|
||||
|
||||
|
@ -5,22 +5,20 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Scoring
|
||||
{
|
||||
internal class OsuScoreProcessor : ScoreProcessor<OsuHitObject>
|
||||
internal class OsuScoreProcessor : ScoreProcessor
|
||||
{
|
||||
public OsuScoreProcessor(DrawableRuleset<OsuHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
public OsuScoreProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
private float hpDrainRate;
|
||||
|
||||
protected override void ApplyBeatmap(Beatmap<OsuHitObject> beatmap)
|
||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
base.ApplyBeatmap(beatmap);
|
||||
|
||||
|
@ -26,14 +26,14 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
{
|
||||
protected new OsuRulesetConfigManager Config => (OsuRulesetConfigManager)base.Config;
|
||||
|
||||
public DrawableOsuRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableOsuRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; // always show the gameplay cursor
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(Beatmap);
|
||||
|
||||
protected override Playfield CreatePlayfield() => new OsuPlayfield();
|
||||
|
||||
|
@ -11,7 +11,6 @@ using osu.Framework.MathUtils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -91,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 768,
|
||||
Children = new[] { drawableRuleset = new DrawableTaikoRuleset(new TaikoRuleset(), beatmap, Array.Empty<Mod>()) }
|
||||
Children = new[] { drawableRuleset = new DrawableTaikoRuleset(new TaikoRuleset(), beatmap.GetPlayableBeatmap(new TaikoRuleset().RulesetInfo)) }
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
{
|
||||
internal class TaikoScoreProcessor : ScoreProcessor<TaikoHitObject>
|
||||
internal class TaikoScoreProcessor : ScoreProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// A value used for calculating <see cref="hpMultiplier"/>.
|
||||
@ -31,16 +31,16 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
/// </summary>
|
||||
private double hpMissMultiplier;
|
||||
|
||||
public TaikoScoreProcessor(DrawableRuleset<TaikoHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
public TaikoScoreProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ApplyBeatmap(Beatmap<TaikoHitObject> beatmap)
|
||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
base.ApplyBeatmap(beatmap);
|
||||
|
||||
hpMultiplier = 1 / (object_count_factor * beatmap.HitObjects.FindAll(o => o is Hit).Count * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
|
||||
hpMultiplier = 1 / (object_count_factor * beatmap.HitObjects.OfType<Hit>().Count() * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
|
||||
|
||||
hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
public class TaikoRuleset : Ruleset
|
||||
{
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableTaikoRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableTaikoRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap);
|
||||
|
||||
public const string SHORT_NAME = "taiko";
|
||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
|
||||
protected override bool UserScrollSpeedAdjustment => false;
|
||||
|
||||
public DrawableTaikoRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableTaikoRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
Direction.Value = ScrollingDirection.Left;
|
||||
@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
new BarLineGenerator<BarLine>(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar.Major ? new DrawableBarLineMajor(bar) : new DrawableBarLine(bar)));
|
||||
}
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(Beatmap);
|
||||
|
||||
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer();
|
||||
|
||||
|
@ -172,7 +172,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
var ruleset = new TestScrollingRuleset();
|
||||
|
||||
drawableRuleset = (TestDrawableScrollingRuleset)ruleset.CreateDrawableRulesetWith(CreateWorkingBeatmap(beatmap), Array.Empty<Mod>());
|
||||
drawableRuleset = (TestDrawableScrollingRuleset)ruleset.CreateDrawableRulesetWith(CreateWorkingBeatmap(beatmap).GetPlayableBeatmap(ruleset.RulesetInfo));
|
||||
drawableRuleset.FrameStablePlayback = false;
|
||||
|
||||
overrideAction?.Invoke(drawableRuleset);
|
||||
@ -201,7 +201,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => throw new NotImplementedException();
|
||||
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new TestDrawableScrollingRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new TestDrawableScrollingRuleset(this, beatmap, mods);
|
||||
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap);
|
||||
|
||||
@ -222,7 +222,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
public new Bindable<double> TimeRange => base.TimeRange;
|
||||
|
||||
public TestDrawableScrollingRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public TestDrawableScrollingRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
TimeRange.Value = time_range;
|
||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => new Mod[] { };
|
||||
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osu.Framework.IO.File;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Rulesets.Objects.Legacy;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
@ -112,7 +112,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
switch (pair.Key)
|
||||
{
|
||||
case @"AudioFilename":
|
||||
metadata.AudioFile = FileSafety.PathStandardise(pair.Value);
|
||||
metadata.AudioFile = pair.Value.ToStandardisedPath();
|
||||
break;
|
||||
|
||||
case @"AudioLeadIn":
|
||||
@ -300,12 +300,12 @@ namespace osu.Game.Beatmaps.Formats
|
||||
{
|
||||
case EventType.Background:
|
||||
string bgFilename = split[2].Trim('"');
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = FileSafety.PathStandardise(bgFilename);
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = bgFilename.ToStandardisedPath();
|
||||
break;
|
||||
|
||||
case EventType.Video:
|
||||
string videoFilename = split[2].Trim('"');
|
||||
beatmap.BeatmapInfo.Metadata.VideoFile = FileSafety.PathStandardise(videoFilename);
|
||||
beatmap.BeatmapInfo.Metadata.VideoFile = videoFilename.ToStandardisedPath();
|
||||
break;
|
||||
|
||||
case EventType.Break:
|
||||
|
@ -8,8 +8,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.IO.File;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Storyboards;
|
||||
|
||||
@ -335,6 +335,6 @@ namespace osu.Game.Beatmaps.Formats
|
||||
}
|
||||
}
|
||||
|
||||
private string cleanFilename(string path) => FileSafety.PathStandardise(path.Trim('"'));
|
||||
private string cleanFilename(string path) => path.Trim('"').ToStandardisedPath();
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,6 @@ namespace osu.Game.Beatmaps
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param>
|
||||
/// <returns>The converted <see cref="IBeatmap"/>.</returns>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
|
||||
IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods);
|
||||
IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ using osu.Game.Rulesets.Mods;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Storyboards;
|
||||
using osu.Framework.IO.File;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
@ -83,7 +82,10 @@ namespace osu.Game.Beatmaps
|
||||
/// <returns>The absolute path of the output file.</returns>
|
||||
public string Save()
|
||||
{
|
||||
var path = FileSafety.GetTempPath(Guid.NewGuid().ToString().Replace("-", string.Empty) + ".json");
|
||||
string directory = Path.Combine(Path.GetTempPath(), @"osu!");
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
var path = Path.Combine(directory, Guid.NewGuid().ToString().Replace("-", string.Empty) + ".json");
|
||||
using (var sw = new StreamWriter(path))
|
||||
sw.WriteLine(Beatmap.Serialize());
|
||||
return path;
|
||||
@ -97,8 +99,10 @@ namespace osu.Game.Beatmaps
|
||||
/// <returns>The applicable <see cref="IBeatmapConverter"/>.</returns>
|
||||
protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap);
|
||||
|
||||
public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods)
|
||||
public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null)
|
||||
{
|
||||
mods ??= Array.Empty<Mod>();
|
||||
|
||||
var rulesetInstance = ruleset.CreateInstance();
|
||||
|
||||
IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance);
|
||||
|
@ -13,7 +13,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.IO.File;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Threading;
|
||||
@ -493,7 +492,7 @@ namespace osu.Game.Database
|
||||
{
|
||||
fileInfos.Add(new TFileModel
|
||||
{
|
||||
Filename = FileSafety.PathStandardise(file.Substring(prefix.Length)),
|
||||
Filename = file.Substring(prefix.Length).ToStandardisedPath(),
|
||||
FileInfo = files.Add(s)
|
||||
});
|
||||
}
|
||||
|
@ -149,7 +149,15 @@ namespace osu.Game.Database
|
||||
lock (writeLock)
|
||||
{
|
||||
recycleThreadContexts();
|
||||
storage.DeleteDatabase(database_name);
|
||||
|
||||
try
|
||||
{
|
||||
storage.DeleteDatabase(database_name);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// for now we are not sure why file handles are kept open by EF, but this is generally only used in testing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ namespace osu.Game.Rulesets.Edit
|
||||
[Resolved]
|
||||
private BindableBeatDivisor beatDivisor { get; set; }
|
||||
|
||||
private IWorkingBeatmap workingBeatmap;
|
||||
private Beatmap<TObject> playableBeatmap;
|
||||
private IBeatmapProcessor beatmapProcessor;
|
||||
|
||||
@ -71,7 +70,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
try
|
||||
{
|
||||
drawableRulesetWrapper = new DrawableEditRulesetWrapper<TObject>(CreateDrawableRuleset(Ruleset, workingBeatmap, Array.Empty<Mod>()))
|
||||
drawableRulesetWrapper = new DrawableEditRulesetWrapper<TObject>(CreateDrawableRuleset(Ruleset, playableBeatmap))
|
||||
{
|
||||
Clock = framedClock,
|
||||
ProcessCustomClock = false
|
||||
@ -145,8 +144,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
var parentWorkingBeatmap = parent.Get<IBindable<WorkingBeatmap>>().Value;
|
||||
|
||||
playableBeatmap = (Beatmap<TObject>)parentWorkingBeatmap.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty<Mod>());
|
||||
workingBeatmap = new EditorWorkingBeatmap<TObject>(playableBeatmap, parentWorkingBeatmap);
|
||||
playableBeatmap = (Beatmap<TObject>)parentWorkingBeatmap.GetPlayableBeatmap(Ruleset.RulesetInfo);
|
||||
|
||||
beatmapProcessor = Ruleset.CreateBeatmapProcessor(playableBeatmap);
|
||||
|
||||
@ -250,7 +248,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
||||
|
||||
protected abstract DrawableRuleset<TObject> CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods);
|
||||
protected abstract DrawableRuleset<TObject> CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null);
|
||||
|
||||
public void BeginPlacement(HitObject hitObject)
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ namespace osu.Game.Rulesets
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply.</param>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">Unable to successfully load the beatmap to be usable with this ruleset.</exception>
|
||||
/// <returns></returns>
|
||||
public abstract DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods);
|
||||
public abstract DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="IBeatmapConverter"/> to convert a <see cref="IBeatmap"/> to one that is applicable for this <see cref="Ruleset"/>.
|
||||
|
@ -13,13 +13,16 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Scoring
|
||||
{
|
||||
public abstract class ScoreProcessor
|
||||
public class ScoreProcessor
|
||||
{
|
||||
private const double base_portion = 0.3;
|
||||
private const double combo_portion = 0.7;
|
||||
private const double max_score = 1000000;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the <see cref="ScoreProcessor"/> is in a failed state.
|
||||
/// This may occur regardless of whether an <see cref="AllJudged"/> event is invoked.
|
||||
@ -67,11 +70,6 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// </summary>
|
||||
public readonly Bindable<IReadOnlyList<Mod>> Mods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="HitWindows"/> for this processor.
|
||||
/// </summary>
|
||||
public virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||
|
||||
/// <summary>
|
||||
/// The current rank.
|
||||
/// </summary>
|
||||
@ -90,132 +88,23 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// <summary>
|
||||
/// Whether all <see cref="Judgement"/>s have been processed.
|
||||
/// </summary>
|
||||
public virtual bool HasCompleted => false;
|
||||
|
||||
/// <summary>
|
||||
/// The total number of judged <see cref="HitObject"/>s at the current point in time.
|
||||
/// </summary>
|
||||
public int JudgedHits { get; protected set; }
|
||||
public bool HasCompleted => JudgedHits == MaxHits;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this ScoreProcessor has already triggered the failed state.
|
||||
/// </summary>
|
||||
public virtual bool HasFailed { get; private set; }
|
||||
public bool HasFailed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default conditions for failing.
|
||||
/// The maximum number of hits that can be judged.
|
||||
/// </summary>
|
||||
protected virtual bool DefaultFailCondition => Precision.AlmostBigger(Health.MinValue, Health.Value);
|
||||
|
||||
protected ScoreProcessor()
|
||||
{
|
||||
Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); };
|
||||
Accuracy.ValueChanged += delegate
|
||||
{
|
||||
Rank.Value = rankFrom(Accuracy.Value);
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToScoreProcessor>())
|
||||
Rank.Value = mod.AdjustRank(Rank.Value, Accuracy.Value);
|
||||
};
|
||||
}
|
||||
|
||||
private ScoreRank rankFrom(double acc)
|
||||
{
|
||||
if (acc == 1)
|
||||
return ScoreRank.X;
|
||||
if (acc > 0.95)
|
||||
return ScoreRank.S;
|
||||
if (acc > 0.9)
|
||||
return ScoreRank.A;
|
||||
if (acc > 0.8)
|
||||
return ScoreRank.B;
|
||||
if (acc > 0.7)
|
||||
return ScoreRank.C;
|
||||
|
||||
return ScoreRank.D;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this ScoreProcessor to a default state.
|
||||
/// </summary>
|
||||
/// <param name="storeResults">Whether to store the current state of the <see cref="ScoreProcessor"/> for future use.</param>
|
||||
protected virtual void Reset(bool storeResults)
|
||||
{
|
||||
TotalScore.Value = 0;
|
||||
Accuracy.Value = 1;
|
||||
Health.Value = 1;
|
||||
Combo.Value = 0;
|
||||
Rank.Value = ScoreRank.X;
|
||||
HighestCombo.Value = 0;
|
||||
|
||||
JudgedHits = 0;
|
||||
|
||||
HasFailed = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the score is in a failed state and notifies subscribers.
|
||||
/// <para>
|
||||
/// This can only ever notify subscribers once.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
protected void UpdateFailed(JudgementResult result)
|
||||
{
|
||||
if (HasFailed)
|
||||
return;
|
||||
|
||||
if (!DefaultFailCondition && FailConditions?.Invoke(this, result) != true)
|
||||
return;
|
||||
|
||||
if (Failed?.Invoke() != false)
|
||||
HasFailed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies subscribers of <see cref="NewJudgement"/> that a new judgement has occurred.
|
||||
/// </summary>
|
||||
/// <param name="result">The judgement scoring result to notify subscribers of.</param>
|
||||
protected void NotifyNewJudgement(JudgementResult result)
|
||||
{
|
||||
NewJudgement?.Invoke(result);
|
||||
|
||||
if (HasCompleted)
|
||||
AllJudged?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve a score populated with data for the current play this processor is responsible for.
|
||||
/// </summary>
|
||||
public virtual void PopulateScore(ScoreInfo score)
|
||||
{
|
||||
score.TotalScore = (long)Math.Round(TotalScore.Value);
|
||||
score.Combo = Combo.Value;
|
||||
score.MaxCombo = HighestCombo.Value;
|
||||
score.Accuracy = Math.Round(Accuracy.Value, 4);
|
||||
score.Rank = Rank.Value;
|
||||
score.Date = DateTimeOffset.Now;
|
||||
|
||||
var hitWindows = CreateHitWindows();
|
||||
|
||||
foreach (var result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r)))
|
||||
score.Statistics[result] = GetStatistic(result);
|
||||
}
|
||||
|
||||
public abstract int GetStatistic(HitResult result);
|
||||
|
||||
public abstract double GetStandardisedScore();
|
||||
}
|
||||
|
||||
public class ScoreProcessor<TObject> : ScoreProcessor
|
||||
where TObject : HitObject
|
||||
{
|
||||
private const double base_portion = 0.3;
|
||||
private const double combo_portion = 0.7;
|
||||
private const double max_score = 1000000;
|
||||
|
||||
public sealed override bool HasCompleted => JudgedHits == MaxHits;
|
||||
|
||||
protected int MaxHits { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The total number of judged <see cref="HitObject"/>s at the current point in time.
|
||||
/// </summary>
|
||||
public int JudgedHits { get; private set; }
|
||||
|
||||
private double maxHighestCombo;
|
||||
|
||||
private double maxBaseScore;
|
||||
@ -225,17 +114,22 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
private double scoreMultiplier = 1;
|
||||
|
||||
public ScoreProcessor(DrawableRuleset<TObject> drawableRuleset)
|
||||
public ScoreProcessor(IBeatmap beatmap)
|
||||
{
|
||||
Debug.Assert(base_portion + combo_portion == 1.0);
|
||||
|
||||
drawableRuleset.OnNewResult += applyResult;
|
||||
drawableRuleset.OnRevertResult += revertResult;
|
||||
Combo.ValueChanged += combo => HighestCombo.Value = Math.Max(HighestCombo.Value, combo.NewValue);
|
||||
Accuracy.ValueChanged += accuracy =>
|
||||
{
|
||||
Rank.Value = rankFrom(accuracy.NewValue);
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToScoreProcessor>())
|
||||
Rank.Value = mod.AdjustRank(Rank.Value, accuracy.NewValue);
|
||||
};
|
||||
|
||||
ApplyBeatmap(drawableRuleset.Beatmap);
|
||||
ApplyBeatmap(beatmap);
|
||||
|
||||
Reset(false);
|
||||
SimulateAutoplay(drawableRuleset.Beatmap);
|
||||
SimulateAutoplay(beatmap);
|
||||
Reset(true);
|
||||
|
||||
if (maxBaseScore == 0 || maxHighestCombo == 0)
|
||||
@ -257,19 +151,19 @@ namespace osu.Game.Rulesets.Scoring
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies any properties of the <see cref="Beatmap{TObject}"/> which affect scoring to this <see cref="ScoreProcessor{TObject}"/>.
|
||||
/// Applies any properties of the <see cref="IBeatmap"/> which affect scoring to this <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The <see cref="Beatmap{TObject}"/> to read properties from.</param>
|
||||
protected virtual void ApplyBeatmap(Beatmap<TObject> beatmap)
|
||||
/// <param name="beatmap">The <see cref="IBeatmap"/> to read properties from.</param>
|
||||
protected virtual void ApplyBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simulates an autoplay of the <see cref="Beatmap{TObject}"/> to determine scoring values.
|
||||
/// Simulates an autoplay of the <see cref="IBeatmap"/> to determine scoring values.
|
||||
/// </summary>
|
||||
/// <remarks>This provided temporarily. DO NOT USE.</remarks>
|
||||
/// <param name="beatmap">The <see cref="Beatmap{TObject}"/> to simulate.</param>
|
||||
protected virtual void SimulateAutoplay(Beatmap<TObject> beatmap)
|
||||
/// <param name="beatmap">The <see cref="IBeatmap"/> to simulate.</param>
|
||||
protected virtual void SimulateAutoplay(IBeatmap beatmap)
|
||||
{
|
||||
foreach (var obj in beatmap.HitObjects)
|
||||
simulate(obj);
|
||||
@ -289,7 +183,7 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
result.Type = judgement.MaxResult;
|
||||
|
||||
applyResult(result);
|
||||
ApplyResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,22 +191,26 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// Applies the score change of a <see cref="JudgementResult"/> to this <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
/// <param name="result">The <see cref="JudgementResult"/> to apply.</param>
|
||||
private void applyResult(JudgementResult result)
|
||||
public void ApplyResult(JudgementResult result)
|
||||
{
|
||||
ApplyResult(result);
|
||||
updateScore();
|
||||
ApplyResultInternal(result);
|
||||
|
||||
UpdateFailed(result);
|
||||
NotifyNewJudgement(result);
|
||||
updateScore();
|
||||
updateFailed(result);
|
||||
|
||||
NewJudgement?.Invoke(result);
|
||||
|
||||
if (HasCompleted)
|
||||
AllJudged?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the score change of a <see cref="JudgementResult"/> that was applied to this <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
/// <param name="result">The judgement scoring result.</param>
|
||||
private void revertResult(JudgementResult result)
|
||||
public void RevertResult(JudgementResult result)
|
||||
{
|
||||
RevertResult(result);
|
||||
RevertResultInternal(result);
|
||||
updateScore();
|
||||
}
|
||||
|
||||
@ -322,10 +220,10 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// Applies the score change of a <see cref="JudgementResult"/> to this <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Any changes applied via this method can be reverted via <see cref="RevertResult"/>.
|
||||
/// Any changes applied via this method can be reverted via <see cref="RevertResultInternal"/>.
|
||||
/// </remarks>
|
||||
/// <param name="result">The <see cref="JudgementResult"/> to apply.</param>
|
||||
protected virtual void ApplyResult(JudgementResult result)
|
||||
protected virtual void ApplyResultInternal(JudgementResult result)
|
||||
{
|
||||
result.ComboAtJudgement = Combo.Value;
|
||||
result.HighestComboAtJudgement = HighestCombo.Value;
|
||||
@ -372,10 +270,10 @@ namespace osu.Game.Rulesets.Scoring
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the score change of a <see cref="JudgementResult"/> that was applied to this <see cref="ScoreProcessor"/> via <see cref="ApplyResult"/>.
|
||||
/// Reverts the score change of a <see cref="JudgementResult"/> that was applied to this <see cref="ScoreProcessor"/> via <see cref="ApplyResultInternal"/>.
|
||||
/// </summary>
|
||||
/// <param name="result">The judgement scoring result.</param>
|
||||
protected virtual void RevertResult(JudgementResult result)
|
||||
protected virtual void RevertResultInternal(JudgementResult result)
|
||||
{
|
||||
Combo.Value = result.ComboAtJudgement;
|
||||
HighestCombo.Value = result.HighestComboAtJudgement;
|
||||
@ -432,11 +330,49 @@ namespace osu.Game.Rulesets.Scoring
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetStatistic(HitResult result) => scoreResultCounts.GetOrDefault(result);
|
||||
/// <summary>
|
||||
/// Checks if the score is in a failed state and notifies subscribers.
|
||||
/// <para>
|
||||
/// This can only ever notify subscribers once.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
private void updateFailed(JudgementResult result)
|
||||
{
|
||||
if (HasFailed)
|
||||
return;
|
||||
|
||||
public override double GetStandardisedScore() => getScore(ScoringMode.Standardised);
|
||||
if (!DefaultFailCondition && FailConditions?.Invoke(this, result) != true)
|
||||
return;
|
||||
|
||||
protected override void Reset(bool storeResults)
|
||||
if (Failed?.Invoke() != false)
|
||||
HasFailed = true;
|
||||
}
|
||||
|
||||
private ScoreRank rankFrom(double acc)
|
||||
{
|
||||
if (acc == 1)
|
||||
return ScoreRank.X;
|
||||
if (acc > 0.95)
|
||||
return ScoreRank.S;
|
||||
if (acc > 0.9)
|
||||
return ScoreRank.A;
|
||||
if (acc > 0.8)
|
||||
return ScoreRank.B;
|
||||
if (acc > 0.7)
|
||||
return ScoreRank.C;
|
||||
|
||||
return ScoreRank.D;
|
||||
}
|
||||
|
||||
public int GetStatistic(HitResult result) => scoreResultCounts.GetOrDefault(result);
|
||||
|
||||
public double GetStandardisedScore() => getScore(ScoringMode.Standardised);
|
||||
|
||||
/// <summary>
|
||||
/// Resets this ScoreProcessor to a default state.
|
||||
/// </summary>
|
||||
/// <param name="storeResults">Whether to store the current state of the <see cref="ScoreProcessor"/> for future use.</param>
|
||||
protected virtual void Reset(bool storeResults)
|
||||
{
|
||||
scoreResultCounts.Clear();
|
||||
|
||||
@ -447,13 +383,49 @@ namespace osu.Game.Rulesets.Scoring
|
||||
maxBaseScore = baseScore;
|
||||
}
|
||||
|
||||
base.Reset(storeResults);
|
||||
|
||||
JudgedHits = 0;
|
||||
baseScore = 0;
|
||||
rollingMaxBaseScore = 0;
|
||||
bonusScore = 0;
|
||||
|
||||
TotalScore.Value = 0;
|
||||
Accuracy.Value = 1;
|
||||
Health.Value = 1;
|
||||
Combo.Value = 0;
|
||||
Rank.Value = ScoreRank.X;
|
||||
HighestCombo.Value = 0;
|
||||
|
||||
HasFailed = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve a score populated with data for the current play this processor is responsible for.
|
||||
/// </summary>
|
||||
public virtual void PopulateScore(ScoreInfo score)
|
||||
{
|
||||
score.TotalScore = (long)Math.Round(TotalScore.Value);
|
||||
score.Combo = Combo.Value;
|
||||
score.MaxCombo = HighestCombo.Value;
|
||||
score.Accuracy = Math.Round(Accuracy.Value, 4);
|
||||
score.Rank = Rank.Value;
|
||||
score.Date = DateTimeOffset.Now;
|
||||
|
||||
var hitWindows = CreateHitWindows();
|
||||
|
||||
foreach (var result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r)))
|
||||
score.Statistics[result] = GetStatistic(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default conditions for failing.
|
||||
/// </summary>
|
||||
protected virtual bool DefaultFailCondition => Precision.AlmostBigger(Health.MinValue, Health.Value);
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="HitWindows"/> for this processor.
|
||||
/// </summary>
|
||||
public virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="JudgementResult"/> that represents the scoring result for a <see cref="HitObject"/>.
|
||||
/// </summary>
|
||||
|
@ -45,6 +45,10 @@ namespace osu.Game.Rulesets.UI
|
||||
public abstract class DrawableRuleset<TObject> : DrawableRuleset, IProvideCursor, ICanAttachKeyCounter
|
||||
where TObject : HitObject
|
||||
{
|
||||
public override event Action<JudgementResult> OnNewResult;
|
||||
|
||||
public override event Action<JudgementResult> OnRevertResult;
|
||||
|
||||
/// <summary>
|
||||
/// The selected variant.
|
||||
/// </summary>
|
||||
@ -91,20 +95,10 @@ namespace osu.Game.Rulesets.UI
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="JudgementResult"/> has been applied by a <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
public event Action<JudgementResult> OnNewResult;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="JudgementResult"/> is being reverted by a <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
public event Action<JudgementResult> OnRevertResult;
|
||||
|
||||
/// <summary>
|
||||
/// The beatmap.
|
||||
/// </summary>
|
||||
public Beatmap<TObject> Beatmap;
|
||||
public readonly Beatmap<TObject> Beatmap;
|
||||
|
||||
public override IEnumerable<HitObject> Objects => Beatmap.HitObjects;
|
||||
|
||||
@ -124,20 +118,22 @@ namespace osu.Game.Rulesets.UI
|
||||
/// Creates a ruleset visualisation for the provided ruleset and beatmap.
|
||||
/// </summary>
|
||||
/// <param name="ruleset">The ruleset being represented.</param>
|
||||
/// <param name="workingBeatmap">The beatmap to create the hit renderer for.</param>
|
||||
/// <param name="beatmap">The beatmap to create the hit renderer for.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply.</param>
|
||||
protected DrawableRuleset(Ruleset ruleset, IWorkingBeatmap workingBeatmap, IReadOnlyList<Mod> mods)
|
||||
protected DrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
: base(ruleset)
|
||||
{
|
||||
if (workingBeatmap == null)
|
||||
throw new ArgumentException("Beatmap cannot be null.", nameof(workingBeatmap));
|
||||
if (beatmap == null)
|
||||
throw new ArgumentNullException(nameof(beatmap), "Beatmap cannot be null.");
|
||||
|
||||
this.mods = mods.ToArray();
|
||||
if (!(beatmap is Beatmap<TObject> tBeatmap))
|
||||
throw new ArgumentException($"{GetType()} expected the beatmap to contain hitobjects of type {typeof(TObject)}.", nameof(beatmap));
|
||||
|
||||
Beatmap = tBeatmap;
|
||||
this.mods = mods?.ToArray() ?? Array.Empty<Mod>();
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Beatmap = (Beatmap<TObject>)workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);
|
||||
|
||||
KeyBindingInputManager = CreateInputManager();
|
||||
playfield = new Lazy<Playfield>(CreatePlayfield);
|
||||
|
||||
@ -309,7 +305,7 @@ namespace osu.Game.Rulesets.UI
|
||||
/// <returns>The Playfield.</returns>
|
||||
protected abstract Playfield CreatePlayfield();
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor<TObject>(this);
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(Beatmap);
|
||||
|
||||
/// <summary>
|
||||
/// Applies the active mods to this DrawableRuleset.
|
||||
@ -366,6 +362,16 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
public abstract class DrawableRuleset : CompositeDrawable
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="JudgementResult"/> has been applied by a <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
public abstract event Action<JudgementResult> OnNewResult;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="JudgementResult"/> is being reverted by a <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
public abstract event Action<JudgementResult> OnRevertResult;
|
||||
|
||||
/// <summary>
|
||||
/// Whether a replay is currently loaded.
|
||||
/// </summary>
|
||||
|
@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
[Cached(Type = typeof(IScrollingInfo))]
|
||||
private readonly LocalScrollingInfo scrollingInfo;
|
||||
|
||||
protected DrawableScrollingRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
protected DrawableScrollingRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
scrollingInfo = new LocalScrollingInfo();
|
||||
|
@ -4,7 +4,6 @@
|
||||
using System;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -29,14 +28,13 @@ using osu.Game.Input.Bindings;
|
||||
using osu.Game.Screens.Edit.Compose;
|
||||
using osu.Game.Screens.Edit.Setup;
|
||||
using osu.Game.Screens.Edit.Timing;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
public class Editor : OsuScreen, IKeyBindingHandler<GlobalAction>
|
||||
public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4");
|
||||
|
||||
public override float BackgroundParallaxAmount => 0.1f;
|
||||
|
||||
public override bool AllowBackButton => false;
|
||||
@ -250,8 +248,12 @@ namespace osu.Game.Screens.Edit
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
// todo: temporary. we want to be applying dim using the UserDimContainer eventually.
|
||||
Background.FadeColour(Color4.DarkGray, 500);
|
||||
|
||||
Background.EnableUserDim.Value = false;
|
||||
Background.BlurAmount.Value = 0;
|
||||
|
||||
resetTrack(true);
|
||||
}
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Graphics.Video;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates a <see cref="WorkingBeatmap"/> while providing an overridden <see cref="Beatmap{TObject}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject"></typeparam>
|
||||
public class EditorWorkingBeatmap<TObject> : IWorkingBeatmap
|
||||
where TObject : HitObject
|
||||
{
|
||||
private readonly Beatmap<TObject> playableBeatmap;
|
||||
private readonly WorkingBeatmap workingBeatmap;
|
||||
|
||||
public EditorWorkingBeatmap(Beatmap<TObject> playableBeatmap, WorkingBeatmap workingBeatmap)
|
||||
{
|
||||
this.playableBeatmap = playableBeatmap;
|
||||
this.workingBeatmap = workingBeatmap;
|
||||
}
|
||||
|
||||
public IBeatmap Beatmap => workingBeatmap.Beatmap;
|
||||
|
||||
public Texture Background => workingBeatmap.Background;
|
||||
|
||||
public VideoSprite Video => workingBeatmap.Video;
|
||||
|
||||
public Track Track => workingBeatmap.Track;
|
||||
|
||||
public Waveform Waveform => workingBeatmap.Waveform;
|
||||
|
||||
public Storyboard Storyboard => workingBeatmap.Storyboard;
|
||||
|
||||
public ISkin Skin => workingBeatmap.Skin;
|
||||
|
||||
public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods) => playableBeatmap;
|
||||
}
|
||||
}
|
@ -114,32 +114,40 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray();
|
||||
|
||||
WorkingBeatmap working = loadBeatmap();
|
||||
if (Beatmap.Value is DummyWorkingBeatmap)
|
||||
return;
|
||||
|
||||
if (working == null)
|
||||
IBeatmap playableBeatmap = loadPlayableBeatmap();
|
||||
|
||||
if (playableBeatmap == null)
|
||||
return;
|
||||
|
||||
sampleRestart = audio.Samples.Get(@"Gameplay/restart");
|
||||
|
||||
mouseWheelDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableWheel);
|
||||
|
||||
DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value);
|
||||
|
||||
ScoreProcessor = DrawableRuleset.CreateScoreProcessor();
|
||||
ScoreProcessor.Mods.BindTo(Mods);
|
||||
|
||||
if (!ScoreProcessor.Mode.Disabled)
|
||||
config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
|
||||
|
||||
InternalChild = GameplayClockContainer = new GameplayClockContainer(working, Mods.Value, DrawableRuleset.GameplayStartTime);
|
||||
InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime);
|
||||
|
||||
addUnderlayComponents(GameplayClockContainer);
|
||||
addGameplayComponents(GameplayClockContainer, working);
|
||||
addOverlayComponents(GameplayClockContainer, working);
|
||||
addGameplayComponents(GameplayClockContainer, Beatmap.Value);
|
||||
addOverlayComponents(GameplayClockContainer, Beatmap.Value);
|
||||
|
||||
DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true);
|
||||
|
||||
// bind clock into components that require it
|
||||
DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused);
|
||||
|
||||
DrawableRuleset.OnNewResult += ScoreProcessor.ApplyResult;
|
||||
DrawableRuleset.OnRevertResult += ScoreProcessor.RevertResult;
|
||||
|
||||
// Bind ScoreProcessor to ourselves
|
||||
ScoreProcessor.AllJudged += onCompletion;
|
||||
ScoreProcessor.Failed += onFail;
|
||||
@ -247,36 +255,32 @@ namespace osu.Game.Screens.Play
|
||||
&& !DrawableRuleset.HasReplayLoaded.Value
|
||||
&& !breakOverlay.IsBreakTime.Value;
|
||||
|
||||
private WorkingBeatmap loadBeatmap()
|
||||
private IBeatmap loadPlayableBeatmap()
|
||||
{
|
||||
WorkingBeatmap working = Beatmap.Value;
|
||||
if (working is DummyWorkingBeatmap)
|
||||
return null;
|
||||
IBeatmap playable;
|
||||
|
||||
try
|
||||
{
|
||||
var beatmap = working.Beatmap;
|
||||
|
||||
if (beatmap == null)
|
||||
if (Beatmap.Value.Beatmap == null)
|
||||
throw new InvalidOperationException("Beatmap was not loaded");
|
||||
|
||||
rulesetInfo = Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset;
|
||||
rulesetInfo = Ruleset.Value ?? Beatmap.Value.BeatmapInfo.Ruleset;
|
||||
ruleset = rulesetInfo.CreateInstance();
|
||||
|
||||
try
|
||||
{
|
||||
DrawableRuleset = ruleset.CreateDrawableRulesetWith(working, Mods.Value);
|
||||
playable = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, Mods.Value);
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException)
|
||||
{
|
||||
// we may fail to create a DrawableRuleset if the beatmap cannot be loaded with the user's preferred ruleset
|
||||
// let's try again forcing the beatmap's ruleset.
|
||||
rulesetInfo = beatmap.BeatmapInfo.Ruleset;
|
||||
// A playable beatmap may not be creatable with the user's preferred ruleset, so try using the beatmap's default ruleset
|
||||
rulesetInfo = Beatmap.Value.BeatmapInfo.Ruleset;
|
||||
ruleset = rulesetInfo.CreateInstance();
|
||||
DrawableRuleset = ruleset.CreateDrawableRulesetWith(Beatmap.Value, Mods.Value);
|
||||
|
||||
playable = Beatmap.Value.GetPlayableBeatmap(rulesetInfo, Mods.Value);
|
||||
}
|
||||
|
||||
if (!DrawableRuleset.Objects.Any())
|
||||
if (playable.HitObjects.Count == 0)
|
||||
{
|
||||
Logger.Log("Beatmap contains no hit objects!", level: LogLevel.Error);
|
||||
return null;
|
||||
@ -289,7 +293,7 @@ namespace osu.Game.Screens.Play
|
||||
return null;
|
||||
}
|
||||
|
||||
return working;
|
||||
return playable;
|
||||
}
|
||||
|
||||
private void performImmediateExit()
|
||||
|
@ -23,7 +23,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1210.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1212.0" />
|
||||
<PackageReference Include="Sentry" Version="1.2.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
|
@ -74,7 +74,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.1210.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.1212.0" />
|
||||
</ItemGroup>
|
||||
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
@ -82,7 +82,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1210.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1212.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
|
Loading…
Reference in New Issue
Block a user