mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 14:57:52 +08:00
Merge branch 'master' into fix-background-screen-crash
This commit is contained in:
commit
2c19790a97
@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
private DrawableFruit createDrawable(int index)
|
private DrawableFruit createDrawable(int index)
|
||||||
{
|
{
|
||||||
Fruit fruit = index == 5
|
Fruit fruit = index == 5
|
||||||
? new BananaShower.Banana
|
? new Banana
|
||||||
{
|
{
|
||||||
StartTime = 1000000000000,
|
StartTime = 1000000000000,
|
||||||
IndexInBeatmap = index,
|
IndexInBeatmap = index,
|
||||||
|
@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
{
|
{
|
||||||
public class CatchBeatmapProcessor : BeatmapProcessor
|
public class CatchBeatmapProcessor : BeatmapProcessor
|
||||||
{
|
{
|
||||||
|
public const int RNG_SEED = 1337;
|
||||||
|
|
||||||
public CatchBeatmapProcessor(IBeatmap beatmap)
|
public CatchBeatmapProcessor(IBeatmap beatmap)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
@ -22,12 +24,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
|
|
||||||
public override void PostProcess()
|
public override void PostProcess()
|
||||||
{
|
{
|
||||||
|
base.PostProcess();
|
||||||
|
|
||||||
applyPositionOffsets();
|
applyPositionOffsets();
|
||||||
|
|
||||||
initialiseHyperDash((List<CatchHitObject>)Beatmap.HitObjects);
|
initialiseHyperDash((List<CatchHitObject>)Beatmap.HitObjects);
|
||||||
|
|
||||||
base.PostProcess();
|
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
foreach (var obj in Beatmap.HitObjects.OfType<CatchHitObject>())
|
foreach (var obj in Beatmap.HitObjects.OfType<CatchHitObject>())
|
||||||
{
|
{
|
||||||
@ -37,8 +39,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public const int RNG_SEED = 1337;
|
|
||||||
|
|
||||||
private void applyPositionOffsets()
|
private void applyPositionOffsets()
|
||||||
{
|
{
|
||||||
var rng = new FastRandom(RNG_SEED);
|
var rng = new FastRandom(RNG_SEED);
|
||||||
@ -49,9 +49,9 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
switch (obj)
|
switch (obj)
|
||||||
{
|
{
|
||||||
case BananaShower bananaShower:
|
case BananaShower bananaShower:
|
||||||
foreach (var nested in bananaShower.NestedHitObjects)
|
foreach (var banana in bananaShower.NestedHitObjects.OfType<Banana>())
|
||||||
{
|
{
|
||||||
((BananaShower.Banana)nested).X = (float)rng.NextDouble();
|
banana.X = (float)rng.NextDouble();
|
||||||
rng.Next(); // osu!stable retrieved a random banana type
|
rng.Next(); // osu!stable retrieved a random banana type
|
||||||
rng.Next(); // osu!stable retrieved a random banana rotation
|
rng.Next(); // osu!stable retrieved a random banana rotation
|
||||||
rng.Next(); // osu!stable retrieved a random banana colour
|
rng.Next(); // osu!stable retrieved a random banana colour
|
||||||
|
36
osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
Normal file
36
osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Judgements
|
||||||
|
{
|
||||||
|
public class CatchBananaJudgement : CatchJudgement
|
||||||
|
{
|
||||||
|
public override bool AffectsCombo => false;
|
||||||
|
|
||||||
|
public override bool ShouldExplode => true;
|
||||||
|
|
||||||
|
protected override int NumericResultFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return 1100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float HealthIncreaseFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
Normal file
32
osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Judgements
|
||||||
|
{
|
||||||
|
public class CatchDropletJudgement : CatchJudgement
|
||||||
|
{
|
||||||
|
protected override int NumericResultFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return 30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float HealthIncreaseFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,51 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Judgements
|
namespace osu.Game.Rulesets.Catch.Judgements
|
||||||
{
|
{
|
||||||
public class CatchJudgement : Judgement
|
public class CatchJudgement : Judgement
|
||||||
{
|
{
|
||||||
// todo: wangs
|
public override HitResult MaxResult => HitResult.Perfect;
|
||||||
|
|
||||||
|
protected override int NumericResultFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return 300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The base health increase for the result achieved.
|
||||||
|
/// </summary>
|
||||||
|
public float HealthIncrease => HealthIncreaseFor(Result);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether fruit on the platter should explode or drop.
|
||||||
|
/// Note that this is only checked if the owning object is also <see cref="IHasComboInformation.LastInCombo" />
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool ShouldExplode => IsHit;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a <see cref="HitResult"/> to a base health increase.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="result">The value to convert.</param>
|
||||||
|
/// <returns>The base health increase.</returns>
|
||||||
|
protected virtual float HealthIncreaseFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return 10.2f;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Judgements
|
||||||
|
{
|
||||||
|
public class CatchTinyDropletJudgement : CatchJudgement
|
||||||
|
{
|
||||||
|
public override bool AffectsCombo => false;
|
||||||
|
|
||||||
|
protected override int NumericResultFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float HealthIncreaseFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
osu.Game.Rulesets.Catch/Objects/Banana.cs
Normal file
10
osu.Game.Rulesets.Catch/Objects/Banana.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Objects
|
||||||
|
{
|
||||||
|
public class Banana : Fruit
|
||||||
|
{
|
||||||
|
public override FruitVisualRepresentation VisualRepresentation => FruitVisualRepresentation.Banana;
|
||||||
|
}
|
||||||
|
}
|
@ -37,10 +37,5 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
public double EndTime => StartTime + Duration;
|
public double EndTime => StartTime + Duration;
|
||||||
|
|
||||||
public double Duration { get; set; }
|
public double Duration { get; set; }
|
||||||
|
|
||||||
public class Banana : Fruit
|
|
||||||
{
|
|
||||||
public override FruitVisualRepresentation VisualRepresentation => FruitVisualRepresentation.Banana;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs
Normal file
17
osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Catch.Judgements;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
|
{
|
||||||
|
public class DrawableBanana : DrawableFruit
|
||||||
|
{
|
||||||
|
public DrawableBanana(Banana h)
|
||||||
|
: base(h)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override CatchJudgement CreateJudgement() => new CatchBananaJudgement();
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,7 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Judgements;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
{
|
{
|
||||||
@ -24,15 +22,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
|
|
||||||
InternalChild = bananaContainer = new Container { RelativeSizeAxes = Axes.Both };
|
InternalChild = bananaContainer = new Container { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
foreach (var b in s.NestedHitObjects.Cast<BananaShower.Banana>())
|
foreach (var b in s.NestedHitObjects.Cast<Banana>())
|
||||||
AddNested(getVisualRepresentation?.Invoke(b));
|
AddNested(getVisualRepresentation?.Invoke(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
protected override bool ProvidesJudgement => false;
|
||||||
{
|
|
||||||
if (timeOffset >= 0)
|
|
||||||
AddJudgement(new Judgement { Result = NestedHitObjects.Cast<DrawableCatchHitObject>().Any(n => n.Judgements.Any(j => j.IsHit)) ? HitResult.Perfect : HitResult.Miss });
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void AddNested(DrawableHitObject h)
|
protected override void AddNested(DrawableHitObject h)
|
||||||
{
|
{
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Catch.Judgements;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using OpenTK;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using OpenTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
{
|
{
|
||||||
@ -58,9 +58,15 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
if (CheckPosition == null) return;
|
if (CheckPosition == null) return;
|
||||||
|
|
||||||
if (timeOffset >= 0)
|
if (timeOffset >= 0)
|
||||||
AddJudgement(new Judgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss });
|
{
|
||||||
|
var judgement = CreateJudgement();
|
||||||
|
judgement.Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss;
|
||||||
|
AddJudgement(judgement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual CatchJudgement CreateJudgement() => new CatchJudgement();
|
||||||
|
|
||||||
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
||||||
{
|
{
|
||||||
base.SkinChanged(skin, allowFallback);
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using osu.Game.Rulesets.Catch.Judgements;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
{
|
{
|
||||||
@ -23,6 +24,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
Masking = false;
|
Masking = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override CatchJudgement CreateJudgement() => new CatchDropletJudgement();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using OpenTK;
|
||||||
|
using osu.Game.Rulesets.Catch.Judgements;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
|
{
|
||||||
|
public class DrawableTinyDroplet : DrawableDroplet
|
||||||
|
{
|
||||||
|
public DrawableTinyDroplet(Droplet h)
|
||||||
|
: base(h)
|
||||||
|
{
|
||||||
|
Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS) / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override CatchJudgement CreateJudgement() => new CatchTinyDropletJudgement();
|
||||||
|
}
|
||||||
|
}
|
@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Catch.Replays
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h is BananaShower.Banana)
|
if (h is Banana)
|
||||||
{
|
{
|
||||||
// auto bananas unrealistically warp to catch 100% combo.
|
// auto bananas unrealistically warp to catch 100% combo.
|
||||||
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
|
||||||
@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Catch.Replays
|
|||||||
{
|
{
|
||||||
switch (nestedObj)
|
switch (nestedObj)
|
||||||
{
|
{
|
||||||
case BananaShower.Banana _:
|
case Banana _:
|
||||||
case TinyDroplet _:
|
case TinyDroplet _:
|
||||||
case Droplet _:
|
case Droplet _:
|
||||||
case Fruit _:
|
case Fruit _:
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Judgements;
|
using osu.Game.Rulesets.Catch.Judgements;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
@ -17,28 +19,57 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private float hpDrainRate;
|
||||||
|
|
||||||
protected override void SimulateAutoplay(Beatmap<CatchHitObject> beatmap)
|
protected override void SimulateAutoplay(Beatmap<CatchHitObject> beatmap)
|
||||||
{
|
{
|
||||||
|
hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate;
|
||||||
|
|
||||||
foreach (var obj in beatmap.HitObjects)
|
foreach (var obj in beatmap.HitObjects)
|
||||||
{
|
{
|
||||||
switch (obj)
|
switch (obj)
|
||||||
{
|
{
|
||||||
case JuiceStream stream:
|
case JuiceStream stream:
|
||||||
foreach (var _ in stream.NestedHitObjects.Cast<CatchHitObject>())
|
foreach (var nestedObject in stream.NestedHitObjects)
|
||||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
switch (nestedObject)
|
||||||
|
{
|
||||||
|
case TinyDroplet _:
|
||||||
|
AddJudgement(new CatchTinyDropletJudgement { Result = HitResult.Perfect });
|
||||||
|
break;
|
||||||
|
case Droplet _:
|
||||||
|
AddJudgement(new CatchDropletJudgement { Result = HitResult.Perfect });
|
||||||
|
break;
|
||||||
|
case Fruit _:
|
||||||
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BananaShower shower:
|
case BananaShower shower:
|
||||||
foreach (var _ in shower.NestedHitObjects.Cast<CatchHitObject>())
|
foreach (var _ in shower.NestedHitObjects.Cast<CatchHitObject>())
|
||||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
AddJudgement(new CatchBananaJudgement { Result = HitResult.Perfect });
|
||||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
|
||||||
break;
|
break;
|
||||||
case Fruit _:
|
case Fruit _:
|
||||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
base.SimulateAutoplay(beatmap);
|
private const double harshness = 0.01;
|
||||||
|
|
||||||
|
protected override void OnNewJudgement(Judgement judgement)
|
||||||
|
{
|
||||||
|
base.OnNewJudgement(judgement);
|
||||||
|
|
||||||
|
if (judgement.Result == HitResult.Miss)
|
||||||
|
{
|
||||||
|
if (!judgement.IsBonus)
|
||||||
|
Health.Value -= hpDrainRate * (harshness * 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (judgement is CatchJudgement catchJudgement)
|
||||||
|
Health.Value += Math.Max(catchJudgement.HealthIncrease - hpDrainRate, 0) * harshness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,14 +38,16 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
{
|
{
|
||||||
switch (h)
|
switch (h)
|
||||||
{
|
{
|
||||||
|
case Banana banana:
|
||||||
|
return new DrawableBanana(banana);
|
||||||
case Fruit fruit:
|
case Fruit fruit:
|
||||||
return new DrawableFruit(fruit);
|
return new DrawableFruit(fruit);
|
||||||
case JuiceStream stream:
|
case JuiceStream stream:
|
||||||
return new DrawableJuiceStream(stream, GetVisualRepresentation);
|
return new DrawableJuiceStream(stream, GetVisualRepresentation);
|
||||||
case BananaShower banana:
|
case BananaShower shower:
|
||||||
return new DrawableBananaShower(banana, GetVisualRepresentation);
|
return new DrawableBananaShower(shower, GetVisualRepresentation);
|
||||||
case TinyDroplet tiny:
|
case TinyDroplet tiny:
|
||||||
return new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) };
|
return new DrawableTinyDroplet(tiny);
|
||||||
case Droplet droplet:
|
case Droplet droplet:
|
||||||
return new DrawableDroplet(droplet);
|
return new DrawableDroplet(droplet);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Graphics.Textures;
|
|||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.Judgements;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||||
using osu.Game.Rulesets.Catch.Replays;
|
using osu.Game.Rulesets.Catch.Replays;
|
||||||
@ -78,12 +79,11 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
if (!fruit.StaysOnPlate)
|
if (!fruit.StaysOnPlate)
|
||||||
runAfterLoaded(() => MovableCatcher.Explode(caughtFruit));
|
runAfterLoaded(() => MovableCatcher.Explode(caughtFruit));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fruit.HitObject.LastInCombo)
|
if (fruit.HitObject.LastInCombo)
|
||||||
{
|
{
|
||||||
if (judgement.IsHit)
|
if (((CatchJudgement)judgement).ShouldExplode)
|
||||||
runAfterLoaded(() => MovableCatcher.Explode());
|
runAfterLoaded(() => MovableCatcher.Explode());
|
||||||
else
|
else
|
||||||
MovableCatcher.Drop();
|
MovableCatcher.Drop();
|
||||||
|
@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
var obj = new Note { Column = i, StartTime = Time.Current + 2000 };
|
var obj = new Note { Column = i, StartTime = Time.Current + 2000 };
|
||||||
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
|
|
||||||
columns[i].Add(new DrawableNote(obj, columns[i].Action));
|
columns[i].Add(new DrawableNote(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 };
|
var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 };
|
||||||
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
|
|
||||||
columns[i].Add(new DrawableHoldNote(obj, columns[i].Action));
|
columns[i].Add(new DrawableHoldNote(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Height = 0.85f,
|
Height = 0.85f,
|
||||||
AccentColour = Color4.OrangeRed,
|
AccentColour = Color4.OrangeRed,
|
||||||
Action = action,
|
Action = { Value = action },
|
||||||
VisibleTimeRange = { Value = 2000 }
|
VisibleTimeRange = { Value = 2000 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -63,7 +64,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Child = new NoteContainer(direction, $"note, scrolling {direction.ToString().ToLower()}")
|
Child = new NoteContainer(direction, $"note, scrolling {direction.ToString().ToLower()}")
|
||||||
{
|
{
|
||||||
Child = new DrawableNote(note, ManiaAction.Key1) { AccentColour = Color4.OrangeRed }
|
Child = new DrawableNote(note) { AccentColour = Color4.OrangeRed }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -78,7 +79,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Child = new NoteContainer(direction, $"hold note, scrolling {direction.ToString().ToLower()}")
|
Child = new NoteContainer(direction, $"hold note, scrolling {direction.ToString().ToLower()}")
|
||||||
{
|
{
|
||||||
Child = new DrawableHoldNote(note, ManiaAction.Key1)
|
Child = new DrawableHoldNote(note)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
AccentColour = Color4.OrangeRed,
|
AccentColour = Color4.OrangeRed,
|
||||||
@ -136,6 +137,13 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||||
|
{
|
||||||
|
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||||
|
dependencies.CacheAs<IBindable<ManiaAction>>(new Bindable<ManiaAction>());
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
var obj = new Note { Column = i, StartTime = Time.Current + 2000 };
|
var obj = new Note { Column = i, StartTime = Time.Current + 2000 };
|
||||||
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
|
|
||||||
stage.Add(new DrawableNote(obj, stage.Columns[i].Action));
|
stage.Add(new DrawableNote(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 };
|
var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 };
|
||||||
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
|
|
||||||
stage.Add(new DrawableHoldNote(obj, stage.Columns[i].Action));
|
stage.Add(new DrawableHoldNote(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
|||||||
public class HoldNoteJudgement : ManiaJudgement
|
public class HoldNoteJudgement : ManiaJudgement
|
||||||
{
|
{
|
||||||
public override bool AffectsCombo => false;
|
public override bool AffectsCombo => false;
|
||||||
|
|
||||||
protected override int NumericResultFor(HitResult result) => 0;
|
protected override int NumericResultFor(HitResult result) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
private readonly Container<DrawableHoldNoteTick> tickContainer;
|
private readonly Container<DrawableHoldNoteTick> tickContainer;
|
||||||
|
|
||||||
public DrawableHoldNote(HoldNote hitObject, ManiaAction action)
|
public DrawableHoldNote(HoldNote hitObject)
|
||||||
: base(hitObject, action)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
|
||||||
@ -57,12 +57,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
HoldStartTime = () => holdStartTime
|
HoldStartTime = () => holdStartTime
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
head = new DrawableHeadNote(this, action)
|
head = new DrawableHeadNote(this)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre
|
Origin = Anchor.TopCentre
|
||||||
},
|
},
|
||||||
tail = new DrawableTailNote(this, action)
|
tail = new DrawableTailNote(this)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre
|
Origin = Anchor.TopCentre
|
||||||
@ -118,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
if (Time.Current < HitObject.StartTime || Time.Current > HitObject.EndTime)
|
if (Time.Current < HitObject.StartTime || Time.Current > HitObject.EndTime)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (action != Action)
|
if (action != Action.Value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// The user has pressed during the body of the hold note, after the head note and its hit windows have passed
|
// The user has pressed during the body of the hold note, after the head note and its hit windows have passed
|
||||||
@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
if (!holdStartTime.HasValue)
|
if (!holdStartTime.HasValue)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (action != Action)
|
if (action != Action.Value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
holdStartTime = null;
|
holdStartTime = null;
|
||||||
@ -154,8 +154,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
private readonly DrawableHoldNote holdNote;
|
private readonly DrawableHoldNote holdNote;
|
||||||
|
|
||||||
public DrawableHeadNote(DrawableHoldNote holdNote, ManiaAction action)
|
public DrawableHeadNote(DrawableHoldNote holdNote)
|
||||||
: base(holdNote.HitObject.Head, action)
|
: base(holdNote.HitObject.Head)
|
||||||
{
|
{
|
||||||
this.holdNote = holdNote;
|
this.holdNote = holdNote;
|
||||||
}
|
}
|
||||||
@ -191,8 +191,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
private readonly DrawableHoldNote holdNote;
|
private readonly DrawableHoldNote holdNote;
|
||||||
|
|
||||||
public DrawableTailNote(DrawableHoldNote holdNote, ManiaAction action)
|
public DrawableTailNote(DrawableHoldNote holdNote)
|
||||||
: base(holdNote.HitObject.Tail, action)
|
: base(holdNote.HitObject.Tail)
|
||||||
{
|
{
|
||||||
this.holdNote = holdNote;
|
this.holdNote = holdNote;
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
if (!holdNote.holdStartTime.HasValue)
|
if (!holdNote.holdStartTime.HasValue)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (action != Action)
|
if (action != Action.Value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
UpdateJudgement(true);
|
UpdateJudgement(true);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -10,30 +11,26 @@ using osu.Game.Rulesets.UI.Scrolling;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||||
{
|
{
|
||||||
public abstract class DrawableManiaHitObject<TObject> : DrawableHitObject<ManiaHitObject>
|
public abstract class DrawableManiaHitObject : DrawableHitObject<ManiaHitObject>
|
||||||
where TObject : ManiaHitObject
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The key that will trigger input for this hit object.
|
/// The <see cref="ManiaAction"/> which causes this <see cref="DrawableManiaHitObject{TObject}"/> to be hit.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected ManiaAction Action { get; }
|
protected readonly IBindable<ManiaAction> Action = new Bindable<ManiaAction>();
|
||||||
|
|
||||||
public new TObject HitObject;
|
|
||||||
|
|
||||||
protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null)
|
protected DrawableManiaHitObject(ManiaHitObject hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
HitObject = hitObject;
|
|
||||||
|
|
||||||
if (action != null)
|
|
||||||
Action = action.Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(IScrollingInfo scrollingInfo)
|
private void load([CanBeNull] IBindable<ManiaAction> action, [NotNull] IScrollingInfo scrollingInfo)
|
||||||
{
|
{
|
||||||
|
if (action != null)
|
||||||
|
Action.BindTo(action);
|
||||||
|
|
||||||
Direction.BindTo(scrollingInfo.Direction);
|
Direction.BindTo(scrollingInfo.Direction);
|
||||||
Direction.BindValueChanged(OnDirectionChanged, true);
|
Direction.BindValueChanged(OnDirectionChanged, true);
|
||||||
}
|
}
|
||||||
@ -42,6 +39,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
Anchor = Origin = direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
|
Anchor = Origin = direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class DrawableManiaHitObject<TObject> : DrawableManiaHitObject
|
||||||
|
where TObject : ManiaHitObject
|
||||||
|
{
|
||||||
|
public new readonly TObject HitObject;
|
||||||
|
|
||||||
|
protected DrawableManiaHitObject(TObject hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
HitObject = hitObject;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void UpdateState(ArmedState state)
|
protected override void UpdateState(ArmedState state)
|
||||||
{
|
{
|
||||||
|
@ -20,8 +20,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
private readonly NotePiece headPiece;
|
private readonly NotePiece headPiece;
|
||||||
|
|
||||||
public DrawableNote(Note hitObject, ManiaAction action)
|
public DrawableNote(Note hitObject)
|
||||||
: base(hitObject, action)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
public virtual bool OnPressed(ManiaAction action)
|
public virtual bool OnPressed(ManiaAction action)
|
||||||
{
|
{
|
||||||
if (action != Action)
|
if (action != Action.Value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return UpdateJudgement(true);
|
return UpdateJudgement(true);
|
||||||
|
@ -7,6 +7,8 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Mania.UI.Components;
|
using osu.Game.Rulesets.Mania.UI.Components;
|
||||||
@ -19,21 +21,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
private const float column_width = 45;
|
private const float column_width = 45;
|
||||||
private const float special_column_width = 70;
|
private const float special_column_width = 70;
|
||||||
|
|
||||||
private ManiaAction action;
|
public readonly Bindable<ManiaAction> Action = new Bindable<ManiaAction>();
|
||||||
|
|
||||||
public ManiaAction Action
|
|
||||||
{
|
|
||||||
get => action;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (action == value)
|
|
||||||
return;
|
|
||||||
action = value;
|
|
||||||
|
|
||||||
background.Action = value;
|
|
||||||
keyArea.Action = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly ColumnBackground background;
|
private readonly ColumnBackground background;
|
||||||
private readonly ColumnKeyArea keyArea;
|
private readonly ColumnKeyArea keyArea;
|
||||||
@ -130,6 +118,13 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||||
|
{
|
||||||
|
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||||
|
dependencies.CacheAs<IBindable<ManiaAction>>(Action);
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a DrawableHitObject to this Playfield.
|
/// Adds a DrawableHitObject to this Playfield.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
{
|
{
|
||||||
public class ColumnBackground : CompositeDrawable, IKeyBindingHandler<ManiaAction>, IHasAccentColour
|
public class ColumnBackground : CompositeDrawable, IKeyBindingHandler<ManiaAction>, IHasAccentColour
|
||||||
{
|
{
|
||||||
public ManiaAction Action;
|
private readonly IBindable<ManiaAction> action = new Bindable<ManiaAction>();
|
||||||
|
|
||||||
private Box background;
|
private Box background;
|
||||||
private Box backgroundOverlay;
|
private Box backgroundOverlay;
|
||||||
@ -25,8 +25,10 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(IScrollingInfo scrollingInfo)
|
private void load(IBindable<ManiaAction> action, IScrollingInfo scrollingInfo)
|
||||||
{
|
{
|
||||||
|
this.action.BindTo(action);
|
||||||
|
|
||||||
InternalChildren = new[]
|
InternalChildren = new[]
|
||||||
{
|
{
|
||||||
background = new Box
|
background = new Box
|
||||||
@ -91,14 +93,14 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
|
|
||||||
public bool OnPressed(ManiaAction action)
|
public bool OnPressed(ManiaAction action)
|
||||||
{
|
{
|
||||||
if (action == Action)
|
if (action == this.action.Value)
|
||||||
backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint);
|
backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnReleased(ManiaAction action)
|
public bool OnReleased(ManiaAction action)
|
||||||
{
|
{
|
||||||
if (action == Action)
|
if (action == this.action.Value)
|
||||||
backgroundOverlay.FadeTo(0, 250, Easing.OutQuint);
|
backgroundOverlay.FadeTo(0, 250, Easing.OutQuint);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -21,15 +21,16 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
private const float key_icon_size = 10;
|
private const float key_icon_size = 10;
|
||||||
private const float key_icon_corner_radius = 3;
|
private const float key_icon_corner_radius = 3;
|
||||||
|
|
||||||
public ManiaAction Action;
|
private readonly IBindable<ManiaAction> action = new Bindable<ManiaAction>();
|
||||||
|
|
||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
private Container keyIcon;
|
private Container keyIcon;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(IScrollingInfo scrollingInfo)
|
private void load(IBindable<ManiaAction> action, IScrollingInfo scrollingInfo)
|
||||||
{
|
{
|
||||||
|
this.action.BindTo(action);
|
||||||
|
|
||||||
Drawable gradient;
|
Drawable gradient;
|
||||||
|
|
||||||
InternalChildren = new[]
|
InternalChildren = new[]
|
||||||
@ -107,14 +108,14 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
|
|
||||||
public bool OnPressed(ManiaAction action)
|
public bool OnPressed(ManiaAction action)
|
||||||
{
|
{
|
||||||
if (action == Action)
|
if (action == this.action.Value)
|
||||||
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint).Then().ScaleTo(1.3f, 250, Easing.OutQuint);
|
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint).Then().ScaleTo(1.3f, 250, Easing.OutQuint);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnReleased(ManiaAction action)
|
public bool OnReleased(ManiaAction action)
|
||||||
{
|
{
|
||||||
if (action == Action)
|
if (action == this.action.Value)
|
||||||
keyIcon.ScaleTo(1f, 125, Easing.OutQuint);
|
keyIcon.ScaleTo(1f, 125, Easing.OutQuint);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -101,17 +101,15 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
protected override DrawableHitObject<ManiaHitObject> GetVisualRepresentation(ManiaHitObject h)
|
protected override DrawableHitObject<ManiaHitObject> GetVisualRepresentation(ManiaHitObject h)
|
||||||
{
|
{
|
||||||
ManiaAction action = Playfield.Columns.ElementAt(h.Column).Action;
|
switch (h)
|
||||||
|
{
|
||||||
var holdNote = h as HoldNote;
|
case HoldNote holdNote:
|
||||||
if (holdNote != null)
|
return new DrawableHoldNote(holdNote);
|
||||||
return new DrawableHoldNote(holdNote, action);
|
case Note note:
|
||||||
|
return new DrawableNote(note);
|
||||||
var note = h as Note;
|
default:
|
||||||
if (note != null)
|
return null;
|
||||||
return new DrawableNote(note, action);
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Vector2 PlayfieldArea => new Vector2(1, 0.8f);
|
protected override Vector2 PlayfieldArea => new Vector2(1, 0.8f);
|
||||||
|
@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
var column = new Column(direction)
|
var column = new Column(direction)
|
||||||
{
|
{
|
||||||
IsSpecial = isSpecial,
|
IsSpecial = isSpecial,
|
||||||
Action = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++
|
Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ }
|
||||||
};
|
};
|
||||||
|
|
||||||
AddColumn(column);
|
AddColumn(column);
|
||||||
|
@ -15,10 +15,10 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PostProcess()
|
public override void PreProcess()
|
||||||
{
|
{
|
||||||
|
base.PreProcess();
|
||||||
applyStacking((Beatmap<OsuHitObject>)Beatmap);
|
applyStacking((Beatmap<OsuHitObject>)Beatmap);
|
||||||
base.PostProcess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyStacking(Beatmap<OsuHitObject> beatmap)
|
private void applyStacking(Beatmap<OsuHitObject> beatmap)
|
||||||
@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
|
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
|
||||||
double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
|
double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
|
||||||
|
|
||||||
if (objectN.StartTime - endTime > stackThreshold)
|
if (objectN.StartTime - endTime > stackThreshold)
|
||||||
//We are no longer within stacking range of the next object.
|
//We are no longer within stacking range of the next object.
|
||||||
@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
OsuHitObject objectI = beatmap.HitObjects[i];
|
OsuHitObject objectI = beatmap.HitObjects[i];
|
||||||
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
||||||
|
|
||||||
double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
|
double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
|
||||||
|
|
||||||
/* If this object is a hitcircle, then we enter this "special" case.
|
/* If this object is a hitcircle, then we enter this "special" case.
|
||||||
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using OpenTK;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -12,11 +11,6 @@ namespace osu.Game.Rulesets.Osu.Judgements
|
|||||||
{
|
{
|
||||||
public override HitResult MaxResult => HitResult.Great;
|
public override HitResult MaxResult => HitResult.Great;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The positional hit offset.
|
|
||||||
/// </summary>
|
|
||||||
public Vector2 PositionOffset;
|
|
||||||
|
|
||||||
protected override int NumericResultFor(HitResult result)
|
protected override int NumericResultFor(HitResult result)
|
||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
|
@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Osu.Judgements
|
|||||||
public class OsuSliderTailJudgement : OsuJudgement
|
public class OsuSliderTailJudgement : OsuJudgement
|
||||||
{
|
{
|
||||||
public override bool AffectsCombo => false;
|
public override bool AffectsCombo => false;
|
||||||
|
|
||||||
protected override int NumericResultFor(HitResult result) => 0;
|
protected override int NumericResultFor(HitResult result) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
AddJudgement(new OsuJudgement
|
AddJudgement(new OsuJudgement
|
||||||
{
|
{
|
||||||
Result = result,
|
Result = result,
|
||||||
PositionOffset = Vector2.Zero //todo: set to correct value
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +93,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
Body.AccentColour = AccentColour;
|
Body.AccentColour = AccentColour;
|
||||||
Ball.AccentColour = AccentColour;
|
Ball.AccentColour = AccentColour;
|
||||||
|
if (HasNestedHitObjects)
|
||||||
|
foreach (var drawableHitObject in NestedHitObjects)
|
||||||
|
drawableHitObject.AccentColour = AccentColour;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,9 +54,9 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
|
|
||||||
public virtual bool NewCombo { get; set; }
|
public virtual bool NewCombo { get; set; }
|
||||||
|
|
||||||
public int IndexInCurrentCombo { get; set; }
|
public virtual int IndexInCurrentCombo { get; set; }
|
||||||
|
|
||||||
public int ComboIndex { get; set; }
|
public virtual int ComboIndex { get; set; }
|
||||||
|
|
||||||
public bool LastInCombo { get; set; }
|
public bool LastInCombo { get; set; }
|
||||||
|
|
||||||
|
@ -26,6 +26,28 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t);
|
public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t);
|
||||||
public override Vector2 EndPosition => Position + this.CurvePositionAt(1);
|
public override Vector2 EndPosition => Position + this.CurvePositionAt(1);
|
||||||
|
|
||||||
|
public override int ComboIndex
|
||||||
|
{
|
||||||
|
get => base.ComboIndex;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.ComboIndex = value;
|
||||||
|
foreach (var n in NestedHitObjects.OfType<IHasComboInformation>())
|
||||||
|
n.ComboIndex = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int IndexInCurrentCombo
|
||||||
|
{
|
||||||
|
get => base.IndexInCurrentCombo;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.IndexInCurrentCombo = value;
|
||||||
|
foreach (var n in NestedHitObjects.OfType<IHasComboInformation>())
|
||||||
|
n.IndexInCurrentCombo = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public SliderCurve Curve { get; } = new SliderCurve();
|
public SliderCurve Curve { get; } = new SliderCurve();
|
||||||
|
|
||||||
public List<Vector2> ControlPoints
|
public List<Vector2> ControlPoints
|
||||||
@ -147,7 +169,8 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
var distanceProgress = d / length;
|
var distanceProgress = d / length;
|
||||||
var timeProgress = reversed ? 1 - distanceProgress : distanceProgress;
|
var timeProgress = reversed ? 1 - distanceProgress : distanceProgress;
|
||||||
|
|
||||||
var firstSample = Samples.FirstOrDefault(s => s.Name == SampleInfo.HIT_NORMAL) ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
|
var firstSample = Samples.FirstOrDefault(s => s.Name == SampleInfo.HIT_NORMAL)
|
||||||
|
?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
|
||||||
var sampleList = new List<SampleInfo>();
|
var sampleList = new List<SampleInfo>();
|
||||||
|
|
||||||
if (firstSample != null)
|
if (firstSample != null)
|
||||||
|
@ -11,7 +11,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Connections;
|
|||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Osu.Judgements;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.UI
|
namespace osu.Game.Rulesets.Osu.UI
|
||||||
{
|
{
|
||||||
@ -75,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
DrawableOsuJudgement explosion = new DrawableOsuJudgement(judgement, judgedObject)
|
DrawableOsuJudgement explosion = new DrawableOsuJudgement(judgement, judgedObject)
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Position = ((OsuHitObject)judgedObject.HitObject).StackedEndPosition + ((OsuJudgement)judgement).PositionOffset
|
Position = ((OsuHitObject)judgedObject.HitObject).StackedEndPosition
|
||||||
};
|
};
|
||||||
|
|
||||||
judgementLayer.Add(explosion);
|
judgementLayer.Add(explosion);
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
private void loadBarLines()
|
private void loadBarLines()
|
||||||
{
|
{
|
||||||
TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1];
|
TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1];
|
||||||
double lastHitTime = 1 + (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime;
|
double lastHitTime = 1 + ((lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime);
|
||||||
|
|
||||||
var timingPoints = Beatmap.ControlPointInfo.TimingPoints.ToList();
|
var timingPoints = Beatmap.ControlPointInfo.TimingPoints.ToList();
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -17,6 +19,12 @@ namespace osu.Game.Tests.Visual
|
|||||||
[Description("PlaySongSelect leaderboard")]
|
[Description("PlaySongSelect leaderboard")]
|
||||||
public class TestCaseLeaderboard : OsuTestCase
|
public class TestCaseLeaderboard : OsuTestCase
|
||||||
{
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[] {
|
||||||
|
typeof(Placeholder),
|
||||||
|
typeof(MessagePlaceholder),
|
||||||
|
typeof(RetrievalFailurePlaceholder),
|
||||||
|
};
|
||||||
|
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
|
|
||||||
private readonly FailableLeaderboard leaderboard;
|
private readonly FailableLeaderboard leaderboard;
|
||||||
|
@ -66,8 +66,8 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
// General
|
// General
|
||||||
public int AudioLeadIn { get; set; }
|
public int AudioLeadIn { get; set; }
|
||||||
public bool Countdown { get; set; }
|
public bool Countdown { get; set; } = true;
|
||||||
public float StackLeniency { get; set; }
|
public float StackLeniency { get; set; } = 0.7f;
|
||||||
public bool SpecialStyle { get; set; }
|
public bool SpecialStyle { get; set; }
|
||||||
|
|
||||||
public int RulesetID { get; set; }
|
public int RulesetID { get; set; }
|
||||||
|
@ -138,7 +138,7 @@ namespace osu.Game.Beatmaps
|
|||||||
PostNotification?.Invoke(new SimpleNotification
|
PostNotification?.Invoke(new SimpleNotification
|
||||||
{
|
{
|
||||||
Icon = FontAwesome.fa_superpowers,
|
Icon = FontAwesome.fa_superpowers,
|
||||||
Text = "You gotta be a supporter to download for now 'yo"
|
Text = "You gotta be an osu!supporter to download for now 'yo"
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -69,11 +69,22 @@ namespace osu.Game.Beatmaps
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return new TrackVirtual();
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Waveform GetWaveform() => new Waveform(store.GetStream(getPathForFile(Metadata.AudioFile)));
|
protected override Waveform GetWaveform()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var trackData = store.GetStream(getPathForFile(Metadata.AudioFile));
|
||||||
|
return trackData == null ? null : new Waveform(trackData);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override Storyboard GetStoryboard()
|
protected override Storyboard GetStoryboard()
|
||||||
{
|
{
|
||||||
|
@ -6,23 +6,9 @@ using osu.Game.Rulesets.Objects.Types;
|
|||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
namespace osu.Game.Beatmaps
|
||||||
{
|
{
|
||||||
public interface IBeatmapProcessor
|
|
||||||
{
|
|
||||||
IBeatmap Beatmap { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Post-processes <see cref="Beatmap"/> to add mode-specific components that aren't added during conversion.
|
|
||||||
/// <para>
|
|
||||||
/// An example of such a usage is for combo colours.
|
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
|
||||||
void PostProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes a post-converted Beatmap.
|
/// Provides functionality to alter a <see cref="IBeatmap"/> after it has been converted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TObject">The type of HitObject contained in the Beatmap.</typeparam>
|
|
||||||
public class BeatmapProcessor : IBeatmapProcessor
|
public class BeatmapProcessor : IBeatmapProcessor
|
||||||
{
|
{
|
||||||
public IBeatmap Beatmap { get; }
|
public IBeatmap Beatmap { get; }
|
||||||
@ -32,13 +18,7 @@ namespace osu.Game.Beatmaps
|
|||||||
Beatmap = beatmap;
|
Beatmap = beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public virtual void PreProcess()
|
||||||
/// Post-processes a Beatmap to add mode-specific components that aren't added during conversion.
|
|
||||||
/// <para>
|
|
||||||
/// An example of such a usage is for combo colours.
|
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
|
||||||
public virtual void PostProcess()
|
|
||||||
{
|
{
|
||||||
IHasComboInformation lastObj = null;
|
IHasComboInformation lastObj = null;
|
||||||
|
|
||||||
@ -62,5 +42,9 @@ namespace osu.Game.Beatmaps
|
|||||||
lastObj = obj;
|
lastObj = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void PostProcess()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,13 @@ namespace osu.Game.Beatmaps
|
|||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
|
|
||||||
public int? OnlineBeatmapSetID { get; set; }
|
private int? onlineBeatmapSetID;
|
||||||
|
|
||||||
|
public int? OnlineBeatmapSetID
|
||||||
|
{
|
||||||
|
get { return onlineBeatmapSetID; }
|
||||||
|
set { onlineBeatmapSetID = value > 0 ? value : null; }
|
||||||
|
}
|
||||||
|
|
||||||
public BeatmapMetadata Metadata { get; set; }
|
public BeatmapMetadata Metadata { get; set; }
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
protected override Texture GetBackground() => game?.Textures.Get(@"Backgrounds/bg4");
|
protected override Texture GetBackground() => game?.Textures.Get(@"Backgrounds/bg4");
|
||||||
|
|
||||||
protected override Track GetTrack() => new TrackVirtual();
|
protected override Track GetTrack() => new TrackVirtual { Length = 1000 };
|
||||||
|
|
||||||
private class DummyRulesetInfo : RulesetInfo
|
private class DummyRulesetInfo : RulesetInfo
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,9 @@ using osu.Game.Rulesets.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
namespace osu.Game.Beatmaps
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides functionality to convert a <see cref="IBeatmap"/> for a <see cref="Ruleset"/>.
|
||||||
|
/// </summary>
|
||||||
public interface IBeatmapConverter
|
public interface IBeatmapConverter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
40
osu.Game/Beatmaps/IBeatmapProcessor.cs
Normal file
40
osu.Game/Beatmaps/IBeatmapProcessor.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides functionality to alter a <see cref="IBeatmap"/> after it has been converted.
|
||||||
|
/// </summary>
|
||||||
|
public interface IBeatmapProcessor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="IBeatmap"/> to process. This should already be converted to the applicable <see cref="Ruleset"/>.
|
||||||
|
/// </summary>
|
||||||
|
IBeatmap Beatmap { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes the converted <see cref="Beatmap"/> prior to <see cref="HitObject.ApplyDefaults"/> being invoked.
|
||||||
|
/// <para>
|
||||||
|
/// Nested <see cref="HitObject"/>s generated during <see cref="HitObject.ApplyDefaults"/> will not be present by this point,
|
||||||
|
/// and no mods will have been applied to the <see cref="HitObject"/>s.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This can only be used to add alterations to <see cref="HitObject"/>s generated directly through the conversion process.
|
||||||
|
/// </remarks>
|
||||||
|
void PreProcess();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes the converted <see cref="Beatmap"/> after <see cref="HitObject.ApplyDefaults"/> has been invoked.
|
||||||
|
/// <para>
|
||||||
|
/// Nested <see cref="HitObject"/>s generated during <see cref="HitObject.ApplyDefaults"/> will be present by this point,
|
||||||
|
/// and mods will have been applied to all <see cref="HitObject"/>s.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This should be used to add alterations to <see cref="HitObject"/>s while they are in their most playable state.
|
||||||
|
/// </remarks>
|
||||||
|
void PostProcess();
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@ using osu.Game.Skinning;
|
|||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
namespace osu.Game.Beatmaps
|
||||||
{
|
{
|
||||||
public abstract class WorkingBeatmap : IDisposable
|
public abstract partial class WorkingBeatmap : IDisposable
|
||||||
{
|
{
|
||||||
public readonly BeatmapInfo BeatmapInfo;
|
public readonly BeatmapInfo BeatmapInfo;
|
||||||
|
|
||||||
@ -116,6 +116,10 @@ namespace osu.Game.Beatmaps
|
|||||||
mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty);
|
mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted);
|
||||||
|
|
||||||
|
processor?.PreProcess();
|
||||||
|
|
||||||
// Compute default values for hitobjects, including creating nested hitobjects in-case they're needed
|
// Compute default values for hitobjects, including creating nested hitobjects in-case they're needed
|
||||||
foreach (var obj in converted.HitObjects)
|
foreach (var obj in converted.HitObjects)
|
||||||
obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty);
|
obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty);
|
||||||
@ -124,8 +128,7 @@ namespace osu.Game.Beatmaps
|
|||||||
foreach (var obj in converted.HitObjects)
|
foreach (var obj in converted.HitObjects)
|
||||||
mod.ApplyToHitObject(obj);
|
mod.ApplyToHitObject(obj);
|
||||||
|
|
||||||
// Post-process
|
processor?.PostProcess();
|
||||||
rulesetInstance.CreateBeatmapProcessor(converted)?.PostProcess();
|
|
||||||
|
|
||||||
return converted;
|
return converted;
|
||||||
}
|
}
|
||||||
@ -145,7 +148,7 @@ namespace osu.Game.Beatmaps
|
|||||||
private Track populateTrack()
|
private Track populateTrack()
|
||||||
{
|
{
|
||||||
// we want to ensure that we always have a track, even if it's a fake one.
|
// we want to ensure that we always have a track, even if it's a fake one.
|
||||||
var t = GetTrack() ?? new TrackVirtual();
|
var t = GetTrack() ?? new VirtualBeatmapTrack(Beatmap);
|
||||||
applyRateAdjustments(t);
|
applyRateAdjustments(t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
38
osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs
Normal file
38
osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps
|
||||||
|
{
|
||||||
|
public partial class WorkingBeatmap
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A type of <see cref="TrackVirtual"/> which provides a valid length based on the <see cref="HitObject"/>s of an <see cref="IBeatmap"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected class VirtualBeatmapTrack : TrackVirtual
|
||||||
|
{
|
||||||
|
private const double excess_length = 1000;
|
||||||
|
|
||||||
|
public VirtualBeatmapTrack(IBeatmap beatmap)
|
||||||
|
{
|
||||||
|
var lastObject = beatmap.HitObjects.LastOrDefault();
|
||||||
|
|
||||||
|
switch (lastObject)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
Length = excess_length;
|
||||||
|
break;
|
||||||
|
case IHasEndTime endTime:
|
||||||
|
Length = endTime.EndTime + excess_length;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Length = lastObject.StartTime + excess_length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,16 +8,20 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.Containers
|
namespace osu.Game.Graphics.Containers
|
||||||
{
|
{
|
||||||
public class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner
|
public class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
private SampleChannel samplePopIn;
|
private SampleChannel samplePopIn;
|
||||||
private SampleChannel samplePopOut;
|
private SampleChannel samplePopOut;
|
||||||
|
|
||||||
|
protected virtual bool PlaySamplesOnStateChange => true;
|
||||||
|
|
||||||
private PreviewTrackManager previewTrackManager;
|
private PreviewTrackManager previewTrackManager;
|
||||||
|
|
||||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
||||||
@ -63,18 +67,33 @@ namespace osu.Game.Graphics.Containers
|
|||||||
return base.OnClick(state);
|
return base.OnClick(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool OnPressed(GlobalAction action)
|
||||||
|
{
|
||||||
|
if (action == GlobalAction.Back)
|
||||||
|
{
|
||||||
|
State = Visibility.Hidden;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnReleased(GlobalAction action) => false;
|
||||||
|
|
||||||
private void onStateChanged(Visibility visibility)
|
private void onStateChanged(Visibility visibility)
|
||||||
{
|
{
|
||||||
switch (visibility)
|
switch (visibility)
|
||||||
{
|
{
|
||||||
case Visibility.Visible:
|
case Visibility.Visible:
|
||||||
if (OverlayActivationMode != OverlayActivation.Disabled)
|
if (OverlayActivationMode != OverlayActivation.Disabled)
|
||||||
samplePopIn?.Play();
|
{
|
||||||
|
if (PlaySamplesOnStateChange) samplePopIn?.Play();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
State = Visibility.Hidden;
|
State = Visibility.Hidden;
|
||||||
break;
|
break;
|
||||||
case Visibility.Hidden:
|
case Visibility.Hidden:
|
||||||
samplePopOut?.Play();
|
if (PlaySamplesOnStateChange) samplePopOut?.Play();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -16,6 +17,8 @@ namespace osu.Game.Graphics.Containers
|
|||||||
|
|
||||||
protected override SpriteText CreateSpriteText() => new OsuSpriteText();
|
protected override SpriteText CreateSpriteText() => new OsuSpriteText();
|
||||||
|
|
||||||
|
public void AddArbitraryDrawable(Drawable drawable) => AddInternal(drawable);
|
||||||
|
|
||||||
public void AddIcon(FontAwesome icon, Action<SpriteText> creationParameters = null) => AddText(((char)icon).ToString(), creationParameters);
|
public void AddIcon(FontAwesome icon, Action<SpriteText> creationParameters = null) => AddText(((char)icon).ToString(), creationParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,14 @@ namespace osu.Game.Graphics
|
|||||||
{
|
{
|
||||||
public class DrawableDate : OsuSpriteText, IHasTooltip
|
public class DrawableDate : OsuSpriteText, IHasTooltip
|
||||||
{
|
{
|
||||||
private readonly DateTimeOffset date;
|
protected readonly DateTimeOffset Date;
|
||||||
|
|
||||||
public DrawableDate(DateTimeOffset date)
|
public DrawableDate(DateTimeOffset date)
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
Font = "Exo2.0-RegularItalic";
|
Font = "Exo2.0-RegularItalic";
|
||||||
|
|
||||||
this.date = date.ToLocalTime();
|
Date = date.ToLocalTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -38,7 +38,7 @@ namespace osu.Game.Graphics
|
|||||||
{
|
{
|
||||||
updateTime();
|
updateTime();
|
||||||
|
|
||||||
var diffToNow = DateTimeOffset.Now.Subtract(date);
|
var diffToNow = DateTimeOffset.Now.Subtract(Date);
|
||||||
|
|
||||||
double timeUntilNextUpdate = 1000;
|
double timeUntilNextUpdate = 1000;
|
||||||
if (diffToNow.TotalSeconds > 60)
|
if (diffToNow.TotalSeconds > 60)
|
||||||
@ -58,8 +58,10 @@ namespace osu.Game.Graphics
|
|||||||
|
|
||||||
public override bool HandleMouseInput => true;
|
public override bool HandleMouseInput => true;
|
||||||
|
|
||||||
private void updateTime() => Text = date.Humanize();
|
protected virtual string Format() => Date.Humanize();
|
||||||
|
|
||||||
public string TooltipText => date.ToString();
|
private void updateTime() => Text = Format();
|
||||||
|
|
||||||
|
public virtual string TooltipText => string.Format($"{Date:MMMM d, yyyy h:mm tt \"UTC\"z}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK.Input;
|
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using System;
|
using System;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
@ -19,6 +20,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
public Action Exit;
|
public Action Exit;
|
||||||
|
|
||||||
private bool focus;
|
private bool focus;
|
||||||
|
|
||||||
public bool HoldFocus
|
public bool HoldFocus
|
||||||
{
|
{
|
||||||
get { return focus; }
|
get { return focus; }
|
||||||
@ -26,7 +28,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
focus = value;
|
focus = value;
|
||||||
if (!focus && HasFocus)
|
if (!focus && HasFocus)
|
||||||
GetContainingInputManager().ChangeFocus(null);
|
base.KillFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,18 +43,34 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
{
|
{
|
||||||
if (!args.Repeat && args.Key == Key.Escape)
|
if (!HasFocus) return false;
|
||||||
{
|
|
||||||
if (Text.Length > 0)
|
if (args.Key == Key.Escape)
|
||||||
Text = string.Empty;
|
return false; // disable the framework-level handling of escape key for confority (we use GlobalAction.Back).
|
||||||
else
|
|
||||||
Exit?.Invoke();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnKeyDown(state, args);
|
return base.OnKeyDown(state, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool OnPressed(GlobalAction action)
|
||||||
|
{
|
||||||
|
if (action == GlobalAction.Back)
|
||||||
|
{
|
||||||
|
if (Text.Length > 0)
|
||||||
|
{
|
||||||
|
Text = string.Empty;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnPressed(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void KillFocus()
|
||||||
|
{
|
||||||
|
base.KillFocus();
|
||||||
|
Exit?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
public override bool RequestsFocus => HoldFocus;
|
public override bool RequestsFocus => HoldFocus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
protected override Drawable GetDrawableCharacter(char c) => new PasswordMaskChar(CalculatedTextSize);
|
protected override Drawable GetDrawableCharacter(char c) => new PasswordMaskChar(CalculatedTextSize);
|
||||||
|
|
||||||
public override bool AllowClipboardExport => false;
|
protected override bool AllowClipboardExport => false;
|
||||||
|
|
||||||
private readonly CapsWarning warning;
|
private readonly CapsWarning warning;
|
||||||
|
|
||||||
|
@ -9,10 +9,12 @@ using osu.Framework.Input;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
public class OsuTextBox : TextBox
|
public class OsuTextBox : TextBox, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
protected override Color4 BackgroundUnfocused => Color4.Black.Opacity(0.5f);
|
protected override Color4 BackgroundUnfocused => Color4.Black.Opacity(0.5f);
|
||||||
protected override Color4 BackgroundFocused => OsuColour.Gray(0.3f).Opacity(0.8f);
|
protected override Color4 BackgroundFocused => OsuColour.Gray(0.3f).Opacity(0.8f);
|
||||||
@ -33,10 +35,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
TextContainer.Height = 0.5f;
|
TextContainer.Height = 0.5f;
|
||||||
CornerRadius = 5;
|
CornerRadius = 5;
|
||||||
|
|
||||||
Current.DisabledChanged += disabled =>
|
Current.DisabledChanged += disabled => { Alpha = disabled ? 0.3f : 1; };
|
||||||
{
|
|
||||||
Alpha = disabled ? 0.3f : 1;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -59,5 +58,18 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), TextSize = CalculatedTextSize };
|
protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), TextSize = CalculatedTextSize };
|
||||||
|
|
||||||
|
public virtual bool OnPressed(GlobalAction action)
|
||||||
|
{
|
||||||
|
if (action == GlobalAction.Back)
|
||||||
|
{
|
||||||
|
KillFocus();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnReleased(GlobalAction action) => false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,6 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
{
|
{
|
||||||
if (HandlePendingText(state)) return true;
|
|
||||||
|
|
||||||
if (!state.Keyboard.ControlPressed && !state.Keyboard.ShiftPressed)
|
if (!state.Keyboard.ControlPressed && !state.Keyboard.ShiftPressed)
|
||||||
{
|
{
|
||||||
switch (args.Key)
|
switch (args.Key)
|
||||||
|
376
osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.Designer.cs
generated
Normal file
376
osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.Designer.cs
generated
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using osu.Game.Database;
|
||||||
|
|
||||||
|
namespace osu.Game.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(OsuDbContext))]
|
||||||
|
[Migration("20180628011956_RemoveNegativeSetIDs")]
|
||||||
|
partial class RemoveNegativeSetIDs
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846");
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<float>("ApproachRate");
|
||||||
|
|
||||||
|
b.Property<float>("CircleSize");
|
||||||
|
|
||||||
|
b.Property<float>("DrainRate");
|
||||||
|
|
||||||
|
b.Property<float>("OverallDifficulty");
|
||||||
|
|
||||||
|
b.Property<double>("SliderMultiplier");
|
||||||
|
|
||||||
|
b.Property<double>("SliderTickRate");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapDifficulty");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AudioLeadIn");
|
||||||
|
|
||||||
|
b.Property<int>("BaseDifficultyID");
|
||||||
|
|
||||||
|
b.Property<int>("BeatDivisor");
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.Property<bool>("Countdown");
|
||||||
|
|
||||||
|
b.Property<double>("DistanceSpacing");
|
||||||
|
|
||||||
|
b.Property<int>("GridSize");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<bool>("Hidden");
|
||||||
|
|
||||||
|
b.Property<bool>("LetterboxInBreaks");
|
||||||
|
|
||||||
|
b.Property<string>("MD5Hash");
|
||||||
|
|
||||||
|
b.Property<int?>("MetadataID");
|
||||||
|
|
||||||
|
b.Property<int?>("OnlineBeatmapID");
|
||||||
|
|
||||||
|
b.Property<string>("Path");
|
||||||
|
|
||||||
|
b.Property<int>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<bool>("SpecialStyle");
|
||||||
|
|
||||||
|
b.Property<float>("StackLeniency");
|
||||||
|
|
||||||
|
b.Property<double>("StarDifficulty");
|
||||||
|
|
||||||
|
b.Property<string>("StoredBookmarks");
|
||||||
|
|
||||||
|
b.Property<double>("TimelineZoom");
|
||||||
|
|
||||||
|
b.Property<string>("Version");
|
||||||
|
|
||||||
|
b.Property<bool>("WidescreenStoryboard");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BaseDifficultyID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("Hash");
|
||||||
|
|
||||||
|
b.HasIndex("MD5Hash");
|
||||||
|
|
||||||
|
b.HasIndex("MetadataID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineBeatmapID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Artist");
|
||||||
|
|
||||||
|
b.Property<string>("ArtistUnicode");
|
||||||
|
|
||||||
|
b.Property<string>("AudioFile");
|
||||||
|
|
||||||
|
b.Property<string>("AuthorString")
|
||||||
|
.HasColumnName("Author");
|
||||||
|
|
||||||
|
b.Property<string>("BackgroundFile");
|
||||||
|
|
||||||
|
b.Property<int>("PreviewTime");
|
||||||
|
|
||||||
|
b.Property<string>("Source");
|
||||||
|
|
||||||
|
b.Property<string>("Tags");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TitleUnicode");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapMetadata");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapSetFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int?>("MetadataID");
|
||||||
|
|
||||||
|
b.Property<int?>("OnlineBeatmapSetID");
|
||||||
|
|
||||||
|
b.Property<bool>("Protected");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("DeletePending");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("MetadataID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineBeatmapSetID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("BeatmapSetInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("IntKey")
|
||||||
|
.HasColumnName("Key");
|
||||||
|
|
||||||
|
b.Property<int?>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<string>("StringValue")
|
||||||
|
.HasColumnName("Value");
|
||||||
|
|
||||||
|
b.Property<int?>("Variant");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID", "Variant");
|
||||||
|
|
||||||
|
b.ToTable("Settings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("IntAction")
|
||||||
|
.HasColumnName("Action");
|
||||||
|
|
||||||
|
b.Property<string>("KeysString")
|
||||||
|
.HasColumnName("Keys");
|
||||||
|
|
||||||
|
b.Property<int?>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<int?>("Variant");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("IntAction");
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID", "Variant");
|
||||||
|
|
||||||
|
b.ToTable("KeyBinding");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int>("ReferenceCount");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("ReferenceCount");
|
||||||
|
|
||||||
|
b.ToTable("FileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int?>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<string>("InstantiationInfo");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("ShortName");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("Available");
|
||||||
|
|
||||||
|
b.HasIndex("ShortName")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("RulesetInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int>("SkinInfoID");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("SkinInfoID");
|
||||||
|
|
||||||
|
b.ToTable("SkinFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Creator");
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.ToTable("SkinInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BaseDifficultyID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet")
|
||||||
|
.WithMany("Beatmaps")
|
||||||
|
.HasForeignKey("BeatmapSetInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||||
|
.WithMany("Beatmaps")
|
||||||
|
.HasForeignKey("MetadataID");
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RulesetID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("BeatmapSetInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||||
|
.WithMany("BeatmapSets")
|
||||||
|
.HasForeignKey("MetadataID");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Skinning.SkinInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("SkinInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs
Normal file
19
osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace osu.Game.Migrations
|
||||||
|
{
|
||||||
|
public partial class RemoveNegativeSetIDs : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
// There was a change that baetmaps were being loaded with "-1" online IDs, which is completely incorrect.
|
||||||
|
// This ensures there will not be unique key conflicts as a result of these incorrectly imported beatmaps.
|
||||||
|
migrationBuilder.Sql("UPDATE BeatmapSetInfo SET OnlineBeatmapSetID = null WHERE OnlineBeatmapSetID <= 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -85,7 +85,7 @@ namespace osu.Game
|
|||||||
private OnScreenDisplay onscreenDisplay;
|
private OnScreenDisplay onscreenDisplay;
|
||||||
|
|
||||||
private Bindable<int> configRuleset;
|
private Bindable<int> configRuleset;
|
||||||
public Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
private Bindable<int> configSkin;
|
private Bindable<int> configSkin;
|
||||||
|
|
||||||
@ -147,10 +147,13 @@ namespace osu.Game
|
|||||||
|
|
||||||
dependencies.CacheAs(this);
|
dependencies.CacheAs(this);
|
||||||
|
|
||||||
|
dependencies.CacheAs(ruleset);
|
||||||
|
dependencies.CacheAs<IBindable<RulesetInfo>>(ruleset);
|
||||||
|
|
||||||
// bind config int to database RulesetInfo
|
// bind config int to database RulesetInfo
|
||||||
configRuleset = LocalConfig.GetBindable<int>(OsuSetting.Ruleset);
|
configRuleset = LocalConfig.GetBindable<int>(OsuSetting.Ruleset);
|
||||||
Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First();
|
ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First();
|
||||||
Ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0;
|
ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0;
|
||||||
|
|
||||||
// bind config int to database SkinInfo
|
// bind config int to database SkinInfo
|
||||||
configSkin = LocalConfig.GetBindable<int>(OsuSetting.Skin);
|
configSkin = LocalConfig.GetBindable<int>(OsuSetting.Skin);
|
||||||
@ -216,7 +219,7 @@ namespace osu.Game
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ruleset.Value = s.Ruleset;
|
ruleset.Value = s.Ruleset;
|
||||||
|
|
||||||
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(s.Beatmap);
|
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(s.Beatmap);
|
||||||
Beatmap.Value.Mods.Value = s.Mods;
|
Beatmap.Value.Mods.Value = s.Mods;
|
||||||
@ -550,7 +553,7 @@ namespace osu.Game
|
|||||||
// the use case for not applying is in visual/unit tests.
|
// the use case for not applying is in visual/unit tests.
|
||||||
bool applyRestrictions = !currentScreen?.AllowBeatmapRulesetChange ?? false;
|
bool applyRestrictions = !currentScreen?.AllowBeatmapRulesetChange ?? false;
|
||||||
|
|
||||||
Ruleset.Disabled = applyRestrictions;
|
ruleset.Disabled = applyRestrictions;
|
||||||
Beatmap.Disabled = applyRestrictions;
|
Beatmap.Disabled = applyRestrictions;
|
||||||
|
|
||||||
mainContent.Padding = new MarginPadding { Top = ToolbarOffset };
|
mainContent.Padding = new MarginPadding { Top = ToolbarOffset };
|
||||||
|
@ -30,6 +30,8 @@ namespace osu.Game.Overlays
|
|||||||
State = Visibility.Visible;
|
State = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool PlaySamplesOnStateChange => false;
|
||||||
|
|
||||||
private void onDialogOnStateChanged(VisibilityContainer dialog, Visibility v)
|
private void onDialogOnStateChanged(VisibilityContainer dialog, Visibility v)
|
||||||
{
|
{
|
||||||
if (v != Visibility.Hidden) return;
|
if (v != Visibility.Hidden) return;
|
||||||
|
@ -35,15 +35,13 @@ namespace osu.Game.Overlays.Direct
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuGame game, RulesetStore rulesets, OsuColour colours)
|
private void load(RulesetStore rulesets, OsuColour colours, Bindable<RulesetInfo> ruleset)
|
||||||
{
|
{
|
||||||
DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark;
|
DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark;
|
||||||
|
|
||||||
Ruleset.Value = game?.Ruleset.Value ?? rulesets.GetRuleset(0);
|
Ruleset.Value = ruleset ?? rulesets.GetRuleset(0);
|
||||||
foreach (var r in rulesets.AvailableRulesets)
|
foreach (var r in rulesets.AvailableRulesets)
|
||||||
{
|
|
||||||
modeButtons.Add(new RulesetToggleButton(Ruleset, r));
|
modeButtons.Add(new RulesetToggleButton(Ruleset, r));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RulesetToggleButton : OsuClickableContainer
|
private class RulesetToggleButton : OsuClickableContainer
|
||||||
|
@ -202,9 +202,6 @@ namespace osu.Game.Overlays.KeyBinding
|
|||||||
|
|
||||||
switch (args.Key)
|
switch (args.Key)
|
||||||
{
|
{
|
||||||
case Key.Escape:
|
|
||||||
finalise();
|
|
||||||
return true;
|
|
||||||
case Key.Delete:
|
case Key.Delete:
|
||||||
{
|
{
|
||||||
if (state.Keyboard.ShiftPressed)
|
if (state.Keyboard.ShiftPressed)
|
||||||
|
@ -52,7 +52,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
private void load(OsuColour colours, OsuGame osu, RulesetStore rulesets, AudioManager audio)
|
private void load(OsuColour colours, Bindable<RulesetInfo> ruleset, RulesetStore rulesets, AudioManager audio)
|
||||||
{
|
{
|
||||||
SelectedMods.ValueChanged += selectedModsChanged;
|
SelectedMods.ValueChanged += selectedModsChanged;
|
||||||
|
|
||||||
@ -60,8 +60,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
HighMultiplierColour = colours.Green;
|
HighMultiplierColour = colours.Green;
|
||||||
UnrankedLabel.Colour = colours.Blue;
|
UnrankedLabel.Colour = colours.Blue;
|
||||||
|
|
||||||
if (osu != null)
|
if (ruleset != null)
|
||||||
Ruleset.BindTo(osu.Ruleset);
|
Ruleset.BindTo(ruleset);
|
||||||
else
|
else
|
||||||
Ruleset.Value = rulesets.AvailableRulesets.First();
|
Ruleset.Value = rulesets.AvailableRulesets.First();
|
||||||
|
|
||||||
|
20
osu.Game/Overlays/Profile/Components/DrawableJoinDate.cs
Normal file
20
osu.Game/Overlays/Profile/Components/DrawableJoinDate.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile.Components
|
||||||
|
{
|
||||||
|
public class DrawableJoinDate : DrawableDate
|
||||||
|
{
|
||||||
|
public DrawableJoinDate(DateTimeOffset date)
|
||||||
|
: base(date)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Format() => Text = Date.ToUniversalTime().Year < 2008 ? "Here since the beginning" : $"{Date:MMMM yyyy}";
|
||||||
|
|
||||||
|
public override string TooltipText => $"{Date:MMMM d, yyyy}";
|
||||||
|
}
|
||||||
|
}
|
50
osu.Game/Overlays/Profile/Components/GradeBadge.cs
Normal file
50
osu.Game/Overlays/Profile/Components/GradeBadge.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) 2007-2018 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.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile.Components
|
||||||
|
{
|
||||||
|
public class GradeBadge : Container
|
||||||
|
{
|
||||||
|
private const float width = 50;
|
||||||
|
private readonly string grade;
|
||||||
|
private readonly Sprite badge;
|
||||||
|
private readonly SpriteText numberText;
|
||||||
|
|
||||||
|
public int DisplayCount
|
||||||
|
{
|
||||||
|
set => numberText.Text = value.ToString(@"#,0");
|
||||||
|
}
|
||||||
|
|
||||||
|
public GradeBadge(string grade)
|
||||||
|
{
|
||||||
|
this.grade = grade;
|
||||||
|
Width = width;
|
||||||
|
Height = 41;
|
||||||
|
Add(badge = new Sprite
|
||||||
|
{
|
||||||
|
Width = width,
|
||||||
|
Height = 26
|
||||||
|
});
|
||||||
|
Add(numberText = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-Bold"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
badge.Texture = textures.Get($"Grades/{grade}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Overlays.Profile.Components;
|
||||||
using osu.Game.Overlays.Profile.Header;
|
using osu.Game.Overlays.Profile.Header;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
@ -375,12 +376,12 @@ namespace osu.Game.Overlays.Profile
|
|||||||
|
|
||||||
if (user.JoinDate.ToUniversalTime().Year < 2008)
|
if (user.JoinDate.ToUniversalTime().Year < 2008)
|
||||||
{
|
{
|
||||||
infoTextLeft.AddText("Here since the beginning", boldItalic);
|
infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), lightText);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
infoTextLeft.AddText("Joined ", lightText);
|
infoTextLeft.AddText("Joined ", lightText);
|
||||||
infoTextLeft.AddText(new DrawableDate(user.JoinDate), boldItalic);
|
infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), boldItalic);
|
||||||
}
|
}
|
||||||
|
|
||||||
infoTextLeft.NewLine();
|
infoTextLeft.NewLine();
|
||||||
@ -470,43 +471,5 @@ namespace osu.Game.Overlays.Profile
|
|||||||
|
|
||||||
infoTextRight.NewLine();
|
infoTextRight.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class GradeBadge : Container
|
|
||||||
{
|
|
||||||
private const float width = 50;
|
|
||||||
private readonly string grade;
|
|
||||||
private readonly Sprite badge;
|
|
||||||
private readonly SpriteText numberText;
|
|
||||||
|
|
||||||
public int DisplayCount
|
|
||||||
{
|
|
||||||
set { numberText.Text = value.ToString(@"#,0"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public GradeBadge(string grade)
|
|
||||||
{
|
|
||||||
this.grade = grade;
|
|
||||||
Width = width;
|
|
||||||
Height = 41;
|
|
||||||
Add(badge = new Sprite
|
|
||||||
{
|
|
||||||
Width = width,
|
|
||||||
Height = 26
|
|
||||||
});
|
|
||||||
Add(numberText = new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomCentre,
|
|
||||||
Origin = Anchor.BottomCentre,
|
|
||||||
TextSize = 14,
|
|
||||||
Font = @"Exo2.0-Bold"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(TextureStore textures)
|
|
||||||
{
|
|
||||||
badge.Texture = textures.Get($"Grades/{grade}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,11 +141,11 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.UserSupportFirst:
|
case RecentActivityType.UserSupportFirst:
|
||||||
message = $"{userLinkTemplate()} has become an osu! supporter - thanks for your generosity!";
|
message = $"{userLinkTemplate()} has become an osu!supporter - thanks for your generosity!";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.UserSupportGift:
|
case RecentActivityType.UserSupportGift:
|
||||||
message = $"{userLinkTemplate()} has received the gift of osu! supporter!";
|
message = $"{userLinkTemplate()} has received the gift of osu!supporter!";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.UsernameChange:
|
case RecentActivityType.UsernameChange:
|
||||||
|
@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(RulesetStore rulesets, OsuGame game)
|
private void load(RulesetStore rulesets, Bindable<RulesetInfo> parentRuleset)
|
||||||
{
|
{
|
||||||
this.rulesets = rulesets;
|
this.rulesets = rulesets;
|
||||||
foreach (var r in rulesets.AvailableRulesets)
|
foreach (var r in rulesets.AvailableRulesets)
|
||||||
@ -83,8 +83,8 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
ruleset.ValueChanged += rulesetChanged;
|
ruleset.ValueChanged += rulesetChanged;
|
||||||
ruleset.DisabledChanged += disabledChanged;
|
ruleset.DisabledChanged += disabledChanged;
|
||||||
|
|
||||||
if (game != null)
|
if (parentRuleset != null)
|
||||||
ruleset.BindTo(game.Ruleset);
|
ruleset.BindTo(parentRuleset);
|
||||||
else
|
else
|
||||||
ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault();
|
ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
@ -45,11 +45,15 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
public double TimeOffset { get; set; }
|
public double TimeOffset { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the <see cref="Result"/> should affect the combo portion of the score.
|
/// Whether the <see cref="Result"/> should affect the current combo.
|
||||||
/// If false, the <see cref="Result"/> will be considered for the bonus portion of the score.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual bool AffectsCombo => true;
|
public virtual bool AffectsCombo => true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the <see cref="Result"/> should be counted as base (combo) or bonus score.
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool IsBonus => !AffectsCombo;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The numeric representation for the result achieved.
|
/// The numeric representation for the result achieved.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Objects.Types
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A HitObject that is part of a combo and has extended information about its position relative to other combo objects.
|
|
||||||
/// </summary>
|
|
||||||
public interface IHasComboIndex : IHasCombo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The offset of this hitobject in the current combo.
|
|
||||||
/// </summary>
|
|
||||||
int IndexInCurrentCombo { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The offset of this hitobject in the current combo.
|
|
||||||
/// </summary>
|
|
||||||
int ComboIndex { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether this is the last object in the current combo.
|
|
||||||
/// </summary>
|
|
||||||
bool LastInCombo { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -57,8 +57,18 @@ namespace osu.Game.Rulesets
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap);
|
public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="IBeatmapConverter"/> to convert a <see cref="IBeatmap"/> to one that is applicable for this <see cref="Ruleset"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beatmap">The <see cref="IBeatmap"/> to be converted.</param>
|
||||||
|
/// <returns>The <see cref="IBeatmapConverter"/>.</returns>
|
||||||
public abstract IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap);
|
public abstract IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optionally creates a <see cref="IBeatmapProcessor"/> to alter a <see cref="IBeatmap"/> after it has been converted.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beatmap">The <see cref="IBeatmap"/> to be processed.</param>
|
||||||
|
/// <returns>The <see cref="IBeatmapProcessor"/>.</returns>
|
||||||
public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null;
|
public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null;
|
||||||
|
|
||||||
public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap);
|
public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap);
|
||||||
|
@ -84,10 +84,17 @@ namespace osu.Game.Rulesets
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var instance = r.CreateInstance();
|
var instanceInfo = ((Ruleset)Activator.CreateInstance(Type.GetType(r.InstantiationInfo, asm =>
|
||||||
|
{
|
||||||
|
// for the time being, let's ignore the version being loaded.
|
||||||
|
// this allows for debug builds to successfully load rulesets (even though debug rulesets have a 0.0.0 version).
|
||||||
|
asm.Version = null;
|
||||||
|
return Assembly.Load(asm);
|
||||||
|
}, null), (RulesetInfo)null)).RulesetInfo;
|
||||||
|
|
||||||
r.Name = instance.Description;
|
r.Name = instanceInfo.Name;
|
||||||
r.ShortName = instance.ShortName;
|
r.ShortName = instanceInfo.ShortName;
|
||||||
|
r.InstantiationInfo = instanceInfo.InstantiationInfo;
|
||||||
|
|
||||||
r.Available = true;
|
r.Available = true;
|
||||||
}
|
}
|
||||||
|
@ -261,13 +261,19 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
baseScore += judgement.NumericResult;
|
|
||||||
rollingMaxBaseScore += judgement.MaxNumericResult;
|
|
||||||
|
|
||||||
JudgedHits++;
|
JudgedHits++;
|
||||||
}
|
}
|
||||||
else if (judgement.IsHit)
|
|
||||||
bonusScore += judgement.NumericResult;
|
if (judgement.IsBonus)
|
||||||
|
{
|
||||||
|
if (judgement.IsHit)
|
||||||
|
bonusScore += judgement.NumericResult;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
baseScore += judgement.NumericResult;
|
||||||
|
rollingMaxBaseScore += judgement.MaxNumericResult;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -280,14 +286,18 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
HighestCombo.Value = judgement.HighestComboAtJudgement;
|
HighestCombo.Value = judgement.HighestComboAtJudgement;
|
||||||
|
|
||||||
if (judgement.AffectsCombo)
|
if (judgement.AffectsCombo)
|
||||||
|
JudgedHits--;
|
||||||
|
|
||||||
|
if (judgement.IsBonus)
|
||||||
|
{
|
||||||
|
if (judgement.IsHit)
|
||||||
|
bonusScore -= judgement.NumericResult;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
baseScore -= judgement.NumericResult;
|
baseScore -= judgement.NumericResult;
|
||||||
rollingMaxBaseScore -= judgement.MaxNumericResult;
|
rollingMaxBaseScore -= judgement.MaxNumericResult;
|
||||||
|
|
||||||
JudgedHits--;
|
|
||||||
}
|
}
|
||||||
else if (judgement.IsHit)
|
|
||||||
bonusScore -= judgement.NumericResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateScore()
|
private void updateScore()
|
||||||
|
@ -52,8 +52,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
|
|||||||
if (Beatmap.Value == null)
|
if (Beatmap.Value == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Beatmap.Value.Track.Length == double.PositiveInfinity) return;
|
|
||||||
|
|
||||||
float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth);
|
float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth);
|
||||||
adjustableClock.Seek(markerPos / DrawWidth * Beatmap.Value.Track.Length);
|
adjustableClock.Seek(markerPos / DrawWidth * Beatmap.Value.Track.Length);
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: This should be handled more gracefully
|
timeline.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1);
|
||||||
timeline.RelativeChildSize = Beatmap.Value.Track.Length == double.PositiveInfinity ? Vector2.One : new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Add(Drawable visualisation) => timeline.Add(visualisation);
|
protected void Add(Drawable visualisation) => timeline.Add(visualisation);
|
||||||
|
@ -52,13 +52,11 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
|||||||
WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint);
|
WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint);
|
||||||
|
|
||||||
Beatmap.BindTo(beatmap);
|
Beatmap.BindTo(beatmap);
|
||||||
}
|
Beatmap.BindValueChanged(b =>
|
||||||
|
{
|
||||||
protected override void LoadComplete()
|
waveform.Waveform = b.Waveform;
|
||||||
{
|
track = b.Track;
|
||||||
base.LoadComplete();
|
}, true);
|
||||||
Beatmap.BindValueChanged(b => waveform.Waveform = b.Waveform);
|
|
||||||
waveform.Waveform = Beatmap.Value.Waveform;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -81,6 +79,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private bool trackWasPlaying;
|
private bool trackWasPlaying;
|
||||||
|
|
||||||
|
private Track track;
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
@ -118,21 +118,18 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
|||||||
|
|
||||||
private void seekTrackToCurrent()
|
private void seekTrackToCurrent()
|
||||||
{
|
{
|
||||||
var track = Beatmap.Value.Track;
|
if (!track.IsLoaded)
|
||||||
if (track is TrackVirtual || !track.IsLoaded)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(Beatmap.Value.Track is TrackVirtual))
|
adjustableClock.Seek(Current / Content.DrawWidth * track.Length);
|
||||||
adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scrollToTrackTime()
|
private void scrollToTrackTime()
|
||||||
{
|
{
|
||||||
var track = Beatmap.Value.Track;
|
if (!track.IsLoaded)
|
||||||
if (track is TrackVirtual || !track.IsLoaded)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false);
|
ScrollTo((float)(adjustableClock.CurrentTime / track.Length) * Content.DrawWidth, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
|
@ -148,8 +148,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
case Key.Space:
|
case Key.Space:
|
||||||
logo?.TriggerOnClick(state);
|
logo?.TriggerOnClick(state);
|
||||||
return true;
|
return true;
|
||||||
case Key.Escape:
|
|
||||||
return goBack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -181,16 +179,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnReleased(GlobalAction action)
|
public bool OnReleased(GlobalAction action) => false;
|
||||||
{
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case GlobalAction.Back:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onPlay()
|
private void onPlay()
|
||||||
{
|
{
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using OpenTK.Input;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Menu
|
namespace osu.Game.Screens.Menu
|
||||||
{
|
{
|
||||||
public class ExitConfirmOverlay : HoldToConfirmOverlay
|
public class ExitConfirmOverlay : HoldToConfirmOverlay, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
public bool OnPressed(GlobalAction action)
|
||||||
{
|
{
|
||||||
if (args.Key == Key.Escape && !args.Repeat)
|
if (action == GlobalAction.Back)
|
||||||
{
|
{
|
||||||
BeginConfirm();
|
BeginConfirm();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.OnKeyDown(state, args);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args)
|
public bool OnReleased(GlobalAction action)
|
||||||
{
|
{
|
||||||
if (args.Key == Key.Escape)
|
if (action == GlobalAction.Back)
|
||||||
{
|
{
|
||||||
AbortConfirm();
|
AbortConfirm();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.OnKeyUp(state, args);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Audio;
|
|||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -17,7 +16,6 @@ using osu.Game.Input.Bindings;
|
|||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Input;
|
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
@ -82,22 +80,24 @@ namespace osu.Game.Screens
|
|||||||
private SampleChannel sampleExit;
|
private SampleChannel sampleExit;
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(BindableBeatmap beatmap, OsuGame osuGame, AudioManager audio)
|
private void load(BindableBeatmap beatmap, OsuGame osu, AudioManager audio, Bindable<RulesetInfo> ruleset)
|
||||||
{
|
{
|
||||||
if (beatmap != null)
|
if (beatmap != null)
|
||||||
Beatmap.BindTo(beatmap);
|
Beatmap.BindTo(beatmap);
|
||||||
|
|
||||||
if (osuGame != null)
|
if (ruleset != null)
|
||||||
|
Ruleset.BindTo(ruleset);
|
||||||
|
|
||||||
|
if (osu != null)
|
||||||
{
|
{
|
||||||
Ruleset.BindTo(osuGame.Ruleset);
|
OverlayActivationMode.BindTo(osu.OverlayActivationMode);
|
||||||
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
|
|
||||||
|
|
||||||
updateOverlayStates = () =>
|
updateOverlayStates = () =>
|
||||||
{
|
{
|
||||||
if (HideOverlaysOnEnter)
|
if (HideOverlaysOnEnter)
|
||||||
osuGame.CloseAllOverlays();
|
osu.CloseAllOverlays();
|
||||||
else
|
else
|
||||||
osuGame.Toolbar.State = Visibility.Visible;
|
osu.Toolbar.State = Visibility.Visible;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +106,8 @@ namespace osu.Game.Screens
|
|||||||
|
|
||||||
public bool OnPressed(GlobalAction action)
|
public bool OnPressed(GlobalAction action)
|
||||||
{
|
{
|
||||||
|
if (!IsCurrentScreen) return false;
|
||||||
|
|
||||||
if (action == GlobalAction.Back && AllowBackButton)
|
if (action == GlobalAction.Back && AllowBackButton)
|
||||||
{
|
{
|
||||||
Exit();
|
Exit();
|
||||||
@ -117,20 +119,6 @@ namespace osu.Game.Screens
|
|||||||
|
|
||||||
public bool OnReleased(GlobalAction action) => action == GlobalAction.Back && AllowBackButton;
|
public bool OnReleased(GlobalAction action) => action == GlobalAction.Back && AllowBackButton;
|
||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
|
||||||
{
|
|
||||||
if (args.Repeat || !IsCurrentScreen) return false;
|
|
||||||
|
|
||||||
switch (args.Key)
|
|
||||||
{
|
|
||||||
case Key.Escape:
|
|
||||||
Exit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnKeyDown(state, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnResuming(Screen last)
|
protected override void OnResuming(Screen last)
|
||||||
{
|
{
|
||||||
sampleExit?.Play();
|
sampleExit?.Play();
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Input;
|
|
||||||
using OpenTK.Input;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
@ -21,16 +18,5 @@ namespace osu.Game.Screens.Play
|
|||||||
AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke());
|
AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke());
|
||||||
AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke());
|
AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
|
||||||
{
|
|
||||||
if (!args.Repeat && args.Key == Key.Escape)
|
|
||||||
{
|
|
||||||
InternalButtons.Children.Last().TriggerOnClick();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnKeyDown(state, args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,13 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
public abstract class GameplayMenuOverlay : OverlayContainer
|
public abstract class GameplayMenuOverlay : OverlayContainer, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
private const int transition_duration = 200;
|
private const int transition_duration = 200;
|
||||||
private const int button_height = 70;
|
private const int button_height = 70;
|
||||||
@ -31,6 +34,11 @@ namespace osu.Game.Screens.Play
|
|||||||
public Action OnRetry;
|
public Action OnRetry;
|
||||||
public Action OnQuit;
|
public Action OnQuit;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Action that is invoked when <see cref="GlobalAction.Back"/> is triggered.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual Action BackAction => () => InternalButtons.Children.Last().TriggerOnClick();
|
||||||
|
|
||||||
public abstract string Header { get; }
|
public abstract string Header { get; }
|
||||||
public abstract string Description { get; }
|
public abstract string Description { get; }
|
||||||
|
|
||||||
@ -219,6 +227,19 @@ namespace osu.Game.Screens.Play
|
|||||||
return base.OnKeyDown(state, args);
|
return base.OnKeyDown(state, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool OnPressed(GlobalAction action)
|
||||||
|
{
|
||||||
|
if (action == GlobalAction.Back)
|
||||||
|
{
|
||||||
|
BackAction.Invoke();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnReleased(GlobalAction action) => action == GlobalAction.Back;
|
||||||
|
|
||||||
private void buttonSelectionChanged(DialogButton button, bool isSelected)
|
private void buttonSelectionChanged(DialogButton button, bool isSelected)
|
||||||
{
|
{
|
||||||
if (!isSelected)
|
if (!isSelected)
|
||||||
|
@ -6,11 +6,9 @@ using System.Linq;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input;
|
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK.Input;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
@ -138,16 +136,7 @@ namespace osu.Game.Screens.Play
|
|||||||
public override string Header => "paused";
|
public override string Header => "paused";
|
||||||
public override string Description => "you're not going to do what i think you're going to do, are ya?";
|
public override string Description => "you're not going to do what i think you're going to do, are ya?";
|
||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
protected override Action BackAction => () => InternalButtons.Children.First().TriggerOnClick();
|
||||||
{
|
|
||||||
if (!args.Repeat && args.Key == Key.Escape)
|
|
||||||
{
|
|
||||||
InternalButtons.Children.First().TriggerOnClick();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnKeyDown(state, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
|
@ -49,8 +49,6 @@ namespace osu.Game.Screens.Play
|
|||||||
public bool AllowLeadIn { get; set; } = true;
|
public bool AllowLeadIn { get; set; } = true;
|
||||||
public bool AllowResults { get; set; } = true;
|
public bool AllowResults { get; set; } = true;
|
||||||
|
|
||||||
protected override bool AllowBackButton => false;
|
|
||||||
|
|
||||||
private Bindable<bool> mouseWheelDisabled;
|
private Bindable<bool> mouseWheelDisabled;
|
||||||
private Bindable<double> userAudioOffset;
|
private Bindable<double> userAudioOffset;
|
||||||
|
|
||||||
@ -158,7 +156,8 @@ namespace osu.Game.Screens.Play
|
|||||||
userAudioOffset.TriggerChange();
|
userAudioOffset.TriggerChange();
|
||||||
|
|
||||||
ScoreProcessor = RulesetContainer.CreateScoreProcessor();
|
ScoreProcessor = RulesetContainer.CreateScoreProcessor();
|
||||||
config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
|
if (!ScoreProcessor.Mode.Disabled)
|
||||||
|
config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
|
@ -53,10 +53,10 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load([CanBeNull] OsuGame osuGame)
|
private void load([CanBeNull] Bindable<RulesetInfo> parentRuleset)
|
||||||
{
|
{
|
||||||
if (osuGame != null)
|
if (parentRuleset != null)
|
||||||
ruleset.BindTo(osuGame.Ruleset);
|
ruleset.BindTo(parentRuleset);
|
||||||
ruleset.ValueChanged += _ => updateDisplay();
|
ruleset.ValueChanged += _ => updateDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ namespace osu.Game.Screens.Select
|
|||||||
Sort = sort,
|
Sort = sort,
|
||||||
SearchText = searchTextBox.Text,
|
SearchText = searchTextBox.Text,
|
||||||
AllowConvertedBeatmaps = showConverted,
|
AllowConvertedBeatmaps = showConverted,
|
||||||
Ruleset = ruleset
|
Ruleset = ruleset.Value
|
||||||
};
|
};
|
||||||
|
|
||||||
public Action Exit;
|
public Action Exit;
|
||||||
@ -163,24 +163,23 @@ namespace osu.Game.Screens.Select
|
|||||||
searchTextBox.HoldFocus = true;
|
searchTextBox.HoldFocus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
private readonly IBindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
private Bindable<bool> showConverted;
|
private Bindable<bool> showConverted;
|
||||||
|
|
||||||
public readonly Box Background;
|
public readonly Box Background;
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
private void load(OsuColour colours, OsuGame osu, OsuConfigManager config)
|
private void load(OsuColour colours, IBindable<RulesetInfo> parentRuleset, OsuConfigManager config)
|
||||||
{
|
{
|
||||||
sortTabs.AccentColour = colours.GreenLight;
|
sortTabs.AccentColour = colours.GreenLight;
|
||||||
|
|
||||||
showConverted = config.GetBindable<bool>(OsuSetting.ShowConvertedBeatmaps);
|
showConverted = config.GetBindable<bool>(OsuSetting.ShowConvertedBeatmaps);
|
||||||
showConverted.ValueChanged += val => updateCriteria();
|
showConverted.ValueChanged += val => updateCriteria();
|
||||||
|
|
||||||
if (osu != null)
|
if (parentRuleset != null)
|
||||||
ruleset.BindTo(osu.Ruleset);
|
ruleset.BindTo(parentRuleset);
|
||||||
ruleset.ValueChanged += val => updateCriteria();
|
ruleset.BindValueChanged(val => updateCriteria(), true);
|
||||||
ruleset.TriggerChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCriteria() => FilterChanged?.Invoke(CreateCriteria());
|
private void updateCriteria() => FilterChanged?.Invoke(CreateCriteria());
|
||||||
|
@ -19,7 +19,6 @@ using osu.Game.Online.API;
|
|||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Logging;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
@ -33,7 +32,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
private FillFlowContainer<LeaderboardScore> scrollFlow;
|
private FillFlowContainer<LeaderboardScore> scrollFlow;
|
||||||
|
|
||||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
private readonly IBindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
public Action<Score> ScoreSelected;
|
public Action<Score> ScoreSelected;
|
||||||
|
|
||||||
@ -146,7 +145,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
replacePlaceholder(new MessagePlaceholder(@"Please sign in to view online leaderboards!"));
|
replacePlaceholder(new MessagePlaceholder(@"Please sign in to view online leaderboards!"));
|
||||||
break;
|
break;
|
||||||
case PlaceholderState.NotSupporter:
|
case PlaceholderState.NotSupporter:
|
||||||
replacePlaceholder(new MessagePlaceholder(@"Please invest in a supporter tag to view this leaderboard!"));
|
replacePlaceholder(new MessagePlaceholder(@"Please invest in an osu!supporter tag to view this leaderboard!"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
replacePlaceholder(null);
|
replacePlaceholder(null);
|
||||||
@ -174,9 +173,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
private APIAccess api;
|
private APIAccess api;
|
||||||
private BeatmapInfo beatmap;
|
private BeatmapInfo beatmap;
|
||||||
private OsuGame osuGame;
|
|
||||||
|
|
||||||
private ScheduledDelegate pendingBeatmapSwitch;
|
private ScheduledDelegate pendingUpdateScores;
|
||||||
|
|
||||||
public BeatmapInfo Beatmap
|
public BeatmapInfo Beatmap
|
||||||
{
|
{
|
||||||
@ -189,21 +187,19 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
beatmap = value;
|
beatmap = value;
|
||||||
Scores = null;
|
Scores = null;
|
||||||
|
|
||||||
pendingBeatmapSwitch?.Cancel();
|
updateScores();
|
||||||
pendingBeatmapSwitch = Schedule(updateScores);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
private void load(APIAccess api, OsuGame osuGame)
|
private void load(APIAccess api, IBindable<RulesetInfo> parentRuleset)
|
||||||
{
|
{
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.osuGame = osuGame;
|
|
||||||
|
|
||||||
if (osuGame != null)
|
if (parentRuleset != null)
|
||||||
ruleset.BindTo(osuGame.Ruleset);
|
ruleset.BindTo(parentRuleset);
|
||||||
|
|
||||||
ruleset.ValueChanged += r => updateScores();
|
ruleset.ValueChanged += _ => updateScores();
|
||||||
|
|
||||||
if (api != null)
|
if (api != null)
|
||||||
api.OnStateChange += handleApiStateChange;
|
api.OnStateChange += handleApiStateChange;
|
||||||
@ -231,51 +227,57 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
private void updateScores()
|
private void updateScores()
|
||||||
{
|
{
|
||||||
if (Scope == LeaderboardScope.Local)
|
getScoresRequest?.Cancel();
|
||||||
{
|
getScoresRequest = null;
|
||||||
// TODO: get local scores from wherever here.
|
|
||||||
PlaceholderState = PlaceholderState.NoScores;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Beatmap?.OnlineBeatmapID == null)
|
pendingUpdateScores?.Cancel();
|
||||||
|
pendingUpdateScores = Schedule(() =>
|
||||||
{
|
{
|
||||||
PlaceholderState = PlaceholderState.Unavailable;
|
if (Scope == LeaderboardScope.Local)
|
||||||
return;
|
{
|
||||||
}
|
// TODO: get local scores from wherever here.
|
||||||
|
PlaceholderState = PlaceholderState.NoScores;
|
||||||
if (api?.IsLoggedIn != true)
|
|
||||||
{
|
|
||||||
PlaceholderState = PlaceholderState.NotLoggedIn;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Scope != LeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
|
|
||||||
{
|
|
||||||
PlaceholderState = PlaceholderState.NotSupporter;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlaceholderState = PlaceholderState.Retrieving;
|
|
||||||
loading.Show();
|
|
||||||
|
|
||||||
getScoresRequest = new GetScoresRequest(Beatmap, osuGame?.Ruleset.Value ?? Beatmap.Ruleset, Scope);
|
|
||||||
getScoresRequest.Success += r => Schedule(() =>
|
|
||||||
{
|
|
||||||
Scores = r.Scores;
|
|
||||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
|
||||||
});
|
|
||||||
|
|
||||||
getScoresRequest.Failure += e => Schedule(() =>
|
|
||||||
{
|
|
||||||
if (e is OperationCanceledException)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PlaceholderState = PlaceholderState.NetworkFailure;
|
if (Beatmap?.OnlineBeatmapID == null)
|
||||||
Logger.Error(e, @"Couldn't fetch beatmap scores!");
|
{
|
||||||
|
PlaceholderState = PlaceholderState.Unavailable;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (api?.IsLoggedIn != true)
|
||||||
|
{
|
||||||
|
PlaceholderState = PlaceholderState.NotLoggedIn;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Scope != LeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
|
||||||
|
{
|
||||||
|
PlaceholderState = PlaceholderState.NotSupporter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlaceholderState = PlaceholderState.Retrieving;
|
||||||
|
loading.Show();
|
||||||
|
|
||||||
|
getScoresRequest = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope);
|
||||||
|
getScoresRequest.Success += r => Schedule(() =>
|
||||||
|
{
|
||||||
|
Scores = r.Scores;
|
||||||
|
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||||
|
});
|
||||||
|
|
||||||
|
getScoresRequest.Failure += e => Schedule(() =>
|
||||||
|
{
|
||||||
|
if (e is OperationCanceledException)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlaceholderState = PlaceholderState.NetworkFailure;
|
||||||
|
});
|
||||||
|
|
||||||
|
api.Queue(getScoresRequest);
|
||||||
});
|
});
|
||||||
|
|
||||||
api.Queue(getScoresRequest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Placeholder currentPlaceholder;
|
private Placeholder currentPlaceholder;
|
||||||
@ -331,23 +333,4 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum LeaderboardScope
|
|
||||||
{
|
|
||||||
Local,
|
|
||||||
Country,
|
|
||||||
Global,
|
|
||||||
Friend,
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum PlaceholderState
|
|
||||||
{
|
|
||||||
Successful,
|
|
||||||
Retrieving,
|
|
||||||
NetworkFailure,
|
|
||||||
Unavailable,
|
|
||||||
NoScores,
|
|
||||||
NotLoggedIn,
|
|
||||||
NotSupporter,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
13
osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs
Normal file
13
osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
|
{
|
||||||
|
public enum LeaderboardScope
|
||||||
|
{
|
||||||
|
Local,
|
||||||
|
Country,
|
||||||
|
Global,
|
||||||
|
Friend,
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using OpenTK;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
{
|
{
|
||||||
@ -15,22 +12,13 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
public MessagePlaceholder(string message)
|
public MessagePlaceholder(string message)
|
||||||
{
|
{
|
||||||
Direction = FillDirection.Horizontal;
|
AddIcon(FontAwesome.fa_exclamation_circle, cp =>
|
||||||
AutoSizeAxes = Axes.Both;
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
{
|
||||||
new SpriteIcon
|
cp.TextSize = TEXT_SIZE;
|
||||||
{
|
cp.Padding = new MarginPadding { Right = 10 };
|
||||||
Icon = FontAwesome.fa_exclamation_circle,
|
});
|
||||||
Size = new Vector2(26),
|
|
||||||
Margin = new MarginPadding { Right = 10 },
|
AddText(this.message = message);
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = this.message = message,
|
|
||||||
TextSize = 22,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(Placeholder other) => (other as MessagePlaceholder)?.message == message;
|
public override bool Equals(Placeholder other) => (other as MessagePlaceholder)?.message == message;
|
||||||
|
@ -3,16 +3,27 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
{
|
{
|
||||||
public abstract class Placeholder : FillFlowContainer, IEquatable<Placeholder>
|
public abstract class Placeholder : OsuTextFlowContainer, IEquatable<Placeholder>
|
||||||
{
|
{
|
||||||
|
protected const float TEXT_SIZE = 22;
|
||||||
|
|
||||||
|
public override bool HandleMouseInput => true;
|
||||||
|
|
||||||
protected Placeholder()
|
protected Placeholder()
|
||||||
|
: base(cp => cp.TextSize = TEXT_SIZE)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
TextAnchor = Anchor.TopCentre;
|
||||||
|
|
||||||
|
Padding = new MarginPadding(20);
|
||||||
|
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool Equals(Placeholder other) => GetType() == other?.GetType();
|
public virtual bool Equals(Placeholder other) => GetType() == other?.GetType();
|
||||||
|
16
osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs
Normal file
16
osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
|
{
|
||||||
|
public enum PlaceholderState
|
||||||
|
{
|
||||||
|
Successful,
|
||||||
|
Retrieving,
|
||||||
|
NetworkFailure,
|
||||||
|
Unavailable,
|
||||||
|
NoScores,
|
||||||
|
NotLoggedIn,
|
||||||
|
NotSupporter,
|
||||||
|
}
|
||||||
|
}
|
@ -3,11 +3,9 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
@ -18,22 +16,13 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
public RetrievalFailurePlaceholder()
|
public RetrievalFailurePlaceholder()
|
||||||
{
|
{
|
||||||
Direction = FillDirection.Horizontal;
|
AddArbitraryDrawable(new RetryButton
|
||||||
AutoSizeAxes = Axes.Both;
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
{
|
||||||
new RetryButton
|
Action = () => OnRetry?.Invoke(),
|
||||||
{
|
Padding = new MarginPadding { Right = 10 }
|
||||||
Action = () => OnRetry?.Invoke(),
|
});
|
||||||
Margin = new MarginPadding { Right = 10 },
|
|
||||||
},
|
AddText(@"Couldn't retrieve scores!");
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopLeft,
|
|
||||||
Text = @"Couldn't retrieve scores!",
|
|
||||||
TextSize = 22,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RetryButton : OsuHoverContainer
|
public class RetryButton : OsuHoverContainer
|
||||||
@ -44,18 +33,16 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
public RetryButton()
|
public RetryButton()
|
||||||
{
|
{
|
||||||
Height = 26;
|
AutoSizeAxes = Axes.Both;
|
||||||
Width = 26;
|
|
||||||
Child = new OsuClickableContainer
|
Child = new OsuClickableContainer
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Action = () => Action?.Invoke(),
|
Action = () => Action?.Invoke(),
|
||||||
Child = icon = new SpriteIcon
|
Child = icon = new SpriteIcon
|
||||||
{
|
{
|
||||||
Icon = FontAwesome.fa_refresh,
|
Icon = FontAwesome.fa_refresh,
|
||||||
Size = new Vector2(26),
|
Size = new Vector2(TEXT_SIZE),
|
||||||
Shadow = true,
|
Shadow = true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
@ -17,6 +18,7 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
@ -62,6 +64,8 @@ namespace osu.Game.Screens.Select
|
|||||||
private SampleChannel sampleChangeDifficulty;
|
private SampleChannel sampleChangeDifficulty;
|
||||||
private SampleChannel sampleChangeBeatmap;
|
private SampleChannel sampleChangeBeatmap;
|
||||||
|
|
||||||
|
protected new readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||||
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||||
@ -123,7 +127,7 @@ namespace osu.Game.Screens.Select
|
|||||||
Size = new Vector2(carousel_width, 1),
|
Size = new Vector2(carousel_width, 1),
|
||||||
Anchor = Anchor.CentreRight,
|
Anchor = Anchor.CentreRight,
|
||||||
Origin = Anchor.CentreRight,
|
Origin = Anchor.CentreRight,
|
||||||
SelectionChanged = carouselSelectionChanged,
|
SelectionChanged = updateSelectedBeatmap,
|
||||||
BeatmapSetsChanged = carouselBeatmapsLoaded,
|
BeatmapSetsChanged = carouselBeatmapsLoaded,
|
||||||
},
|
},
|
||||||
FilterControl = new FilterControl
|
FilterControl = new FilterControl
|
||||||
@ -177,9 +181,13 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours)
|
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours)
|
||||||
{
|
{
|
||||||
dependencies.CacheAs(this);
|
dependencies.CacheAs(this);
|
||||||
|
dependencies.CacheAs(Ruleset);
|
||||||
|
dependencies.CacheAs<IBindable<RulesetInfo>>(Ruleset);
|
||||||
|
|
||||||
|
base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce);
|
||||||
|
|
||||||
if (Footer != null)
|
if (Footer != null)
|
||||||
{
|
{
|
||||||
@ -192,9 +200,6 @@ namespace osu.Game.Screens.Select
|
|||||||
if (this.beatmaps == null)
|
if (this.beatmaps == null)
|
||||||
this.beatmaps = beatmaps;
|
this.beatmaps = beatmaps;
|
||||||
|
|
||||||
if (osu != null)
|
|
||||||
Ruleset.BindTo(osu.Ruleset);
|
|
||||||
|
|
||||||
this.beatmaps.ItemAdded += onBeatmapSetAdded;
|
this.beatmaps.ItemAdded += onBeatmapSetAdded;
|
||||||
this.beatmaps.ItemRemoved += onBeatmapSetRemoved;
|
this.beatmaps.ItemRemoved += onBeatmapSetRemoved;
|
||||||
this.beatmaps.BeatmapHidden += onBeatmapHidden;
|
this.beatmaps.BeatmapHidden += onBeatmapHidden;
|
||||||
@ -250,9 +255,6 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
private ScheduledDelegate selectionChangedDebounce;
|
private ScheduledDelegate selectionChangedDebounce;
|
||||||
|
|
||||||
// We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds.
|
|
||||||
private BeatmapInfo beatmapNoDebounce;
|
|
||||||
|
|
||||||
private void workingBeatmapChanged(WorkingBeatmap beatmap)
|
private void workingBeatmapChanged(WorkingBeatmap beatmap)
|
||||||
{
|
{
|
||||||
if (beatmap is DummyWorkingBeatmap) return;
|
if (beatmap is DummyWorkingBeatmap) return;
|
||||||
@ -266,11 +268,17 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds.
|
||||||
|
private BeatmapInfo beatmapNoDebounce;
|
||||||
|
private RulesetInfo rulesetNoDebounce;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// selection has been changed as the result of interaction with the carousel.
|
/// selection has been changed as the result of a user interaction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void carouselSelectionChanged(BeatmapInfo beatmap)
|
private void updateSelectedBeatmap(BeatmapInfo beatmap)
|
||||||
{
|
{
|
||||||
|
var ruleset = base.Ruleset.Value;
|
||||||
|
|
||||||
void performLoad()
|
void performLoad()
|
||||||
{
|
{
|
||||||
// We may be arriving here due to another component changing the bindable Beatmap.
|
// We may be arriving here due to another component changing the bindable Beatmap.
|
||||||
@ -283,15 +291,18 @@ namespace osu.Game.Screens.Select
|
|||||||
ensurePlayingSelected(preview);
|
ensurePlayingSelected(preview);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ruleset.Value = ruleset;
|
||||||
|
|
||||||
UpdateBeatmap(Beatmap.Value);
|
UpdateBeatmap(Beatmap.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beatmap?.Equals(beatmapNoDebounce) == true)
|
if (beatmap?.Equals(beatmapNoDebounce) == true && ruleset?.Equals(rulesetNoDebounce) == true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
selectionChangedDebounce?.Cancel();
|
selectionChangedDebounce?.Cancel();
|
||||||
|
|
||||||
beatmapNoDebounce = beatmap;
|
beatmapNoDebounce = beatmap;
|
||||||
|
rulesetNoDebounce = ruleset;
|
||||||
|
|
||||||
if (beatmap == null)
|
if (beatmap == null)
|
||||||
performLoad();
|
performLoad();
|
||||||
@ -460,7 +471,7 @@ namespace osu.Game.Screens.Select
|
|||||||
{
|
{
|
||||||
// in the case random selection failed, we want to trigger selectionChanged
|
// in the case random selection failed, we want to trigger selectionChanged
|
||||||
// to show the dummy beatmap (we have nothing else to display).
|
// to show the dummy beatmap (we have nothing else to display).
|
||||||
carouselSelectionChanged(null);
|
updateSelectedBeatmap(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Beatmaps
|
namespace osu.Game.Tests.Beatmaps
|
||||||
{
|
{
|
||||||
@ -26,21 +24,6 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
private readonly IBeatmap beatmap;
|
private readonly IBeatmap beatmap;
|
||||||
protected override IBeatmap GetBeatmap() => beatmap;
|
protected override IBeatmap GetBeatmap() => beatmap;
|
||||||
protected override Texture GetBackground() => null;
|
protected override Texture GetBackground() => null;
|
||||||
|
protected override Track GetTrack() => null;
|
||||||
protected override Track GetTrack()
|
|
||||||
{
|
|
||||||
var lastObject = beatmap.HitObjects.LastOrDefault();
|
|
||||||
if (lastObject != null)
|
|
||||||
return new TestTrack(((lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime) + 1000);
|
|
||||||
return new TrackVirtual();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestTrack : TrackVirtual
|
|
||||||
{
|
|
||||||
public TestTrack(double length)
|
|
||||||
{
|
|
||||||
Length = length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2018.626.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2018.629.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.21.1" />
|
<PackageReference Include="SharpCompress" Version="0.17.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
Loading…
Reference in New Issue
Block a user