From c6e26a92ec2a6eae241068ff83f29923e93aa3f1 Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sat, 26 Jan 2019 12:15:45 +0800 Subject: [PATCH 01/62] add wind up and wind down mods --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 5 ++ .../Mods/CatchModWindDown.cs | 11 ++++ .../Mods/CatchModWindUp.cs | 11 ++++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 5 ++ .../Mods/ManiaModWindDown.cs | 11 ++++ .../Mods/ManiaModWindUp.cs | 11 ++++ osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs | 11 ++++ osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs | 11 ++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 1 + .../Mods/TaikoModWindDown.cs | 11 ++++ .../Mods/TaikoModWindUp.cs | 11 ++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 5 ++ osu.Game/Rulesets/Mods/ModDoubleTime.cs | 2 +- osu.Game/Rulesets/Mods/ModHalfTime.cs | 2 +- osu.Game/Rulesets/Mods/ModWindDown.cs | 16 ++++++ osu.Game/Rulesets/Mods/ModWindUp.cs | 53 +++++++++++++++++++ osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 17 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs create mode 100644 osu.Game/Rulesets/Mods/ModWindDown.cs create mode 100644 osu.Game/Rulesets/Mods/ModWindUp.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index a69070e93e..62892a1bdf 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -99,6 +99,11 @@ namespace osu.Game.Rulesets.Catch new MultiMod(new CatchModAutoplay(), new ModCinema()), new CatchModRelax(), }; + case ModType.Fun: + return new Mod[] + { + new MultiMod(new CatchModWindUp(), new CatchModWindDown()) + }; default: return new Mod[] { }; } diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs new file mode 100644 index 0000000000..b442358bc3 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs @@ -0,0 +1,11 @@ +using System; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Catch.Objects; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModWindDown : ModWindDown + { + + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs new file mode 100644 index 0000000000..351ca56175 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs @@ -0,0 +1,11 @@ +using System; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Catch.Objects; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModWindUp : ModWindUp + { + + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 57728dd134..24228dc57e 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -145,6 +145,11 @@ namespace osu.Game.Rulesets.Mania { new MultiMod(new ManiaModAutoplay(), new ModCinema()), }; + case ModType.Fun: + return new Mod[] + { + new MultiMod(new ManiaModWindUp(), new ManiaModWindDown()) + }; default: return new Mod[] { }; } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs new file mode 100644 index 0000000000..05272d8620 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs @@ -0,0 +1,11 @@ +using System; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Mania.Objects; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModWindDown : ModWindDown + { + + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs new file mode 100644 index 0000000000..d9e663c977 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs @@ -0,0 +1,11 @@ +using System; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Mania.Objects; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModWindUp : ModWindUp + { + + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs new file mode 100644 index 0000000000..71035ad8e4 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs @@ -0,0 +1,11 @@ +using System; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModWindDown : ModWindDown + { + + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs new file mode 100644 index 0000000000..6eb4bdf703 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs @@ -0,0 +1,11 @@ +using System; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModWindUp : ModWindUp + { + + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 9415adc411..74e33426a4 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -121,6 +121,7 @@ namespace osu.Game.Rulesets.Osu return new Mod[] { new OsuModTransform(), new OsuModWiggle(), + new MultiMod(new OsuModWindUp(), new OsuModWindDown()) }; default: return new Mod[] { }; diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs new file mode 100644 index 0000000000..2a59c994b0 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs @@ -0,0 +1,11 @@ +using System; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Taiko.Objects; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModWindDown : ModWindDown + { + + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs new file mode 100644 index 0000000000..7aee771ce9 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs @@ -0,0 +1,11 @@ +using System; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Taiko.Objects; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModWindUp : ModWindUp + { + + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 7851a2f919..d9c7703ebf 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -99,6 +99,11 @@ namespace osu.Game.Rulesets.Taiko new MultiMod(new TaikoModAutoplay(), new ModCinema()), new TaikoModRelax(), }; + case ModType.Fun: + return new Mod[] + { + new MultiMod(new TaikoModWindUp(), new TaikoModWindDown()) + }; default: return new Mod[] { }; } diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index b69019cd91..d87fb5de23 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mods public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Zoooooooooom..."; public override bool Ranked => true; - public override Type[] IncompatibleMods => new[] { typeof(ModHalfTime) }; + public override Type[] IncompatibleMods => new[] { typeof(ModHalfTime), typeof(ModWindUp) }; public virtual void ApplyToClock(IAdjustableClock clock) { diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 1cffa37b04..0b421431d3 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mods public override ModType Type => ModType.DifficultyReduction; public override string Description => "Less zoom..."; public override bool Ranked => true; - public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime) }; + public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime), typeof(ModWindUp) }; public virtual void ApplyToClock(IAdjustableClock clock) { diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs new file mode 100644 index 0000000000..9fc65839fd --- /dev/null +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -0,0 +1,16 @@ +using osu.Game.Graphics; +using osu.Game.Rulesets.Objects; + +namespace osu.Game.Rulesets.Mods +{ + public class ModWindDown : ModWindUp + where T : HitObject + { + public override string Name => "Wind Down"; + public override string Acronym => "WD"; + public override string Description => "Slow down."; + public override FontAwesome Icon => FontAwesome.fa_chevron_circle_down; + public override double AppendRate => -0.25; + } + +} \ No newline at end of file diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs new file mode 100644 index 0000000000..5deeff842b --- /dev/null +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Timing; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.Objects; + +namespace osu.Game.Rulesets.Mods +{ + public abstract class ModWindUp : Mod + { + public override string Name => "Wind Up"; + public override string Acronym => "WU"; + public override ModType Type => ModType.Fun; + public override FontAwesome Icon => FontAwesome.fa_chevron_circle_up; + public override string Description => "Crank it up!"; + public override double ScoreMultiplier => 1; + public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime), typeof(ModHalfTime) }; + public abstract double AppendRate { get; } + } + + public class ModWindUp : ModWindUp, IUpdatableByPlayfield, IApplicableToClock, IApplicableToRulesetContainer + where T : HitObject + { + private Track Track; + private IAdjustableClock Clock; + private IHasPitchAdjust ClockAdjust; + public override double AppendRate => 0.5; + + public virtual void ApplyToClock(IAdjustableClock clock) + { + Clock = clock; + ClockAdjust = clock as IHasPitchAdjust; + } + + public virtual void ApplyToRulesetContainer(RulesetContainer ruleset) + { + Track = ruleset.WorkingBeatmap.Track; + } + + public virtual void Update(Playfield playfield) + { + double newRate = 1 + (AppendRate * (Track.CurrentTime / Track.Length)); + Clock.Rate = newRate; + ClockAdjust.PitchAdjust = newRate; + } + } +} \ No newline at end of file diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 0d020238aa..dfcd2f7602 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -215,7 +215,7 @@ namespace osu.Game.Rulesets.UI /// /// The this was created with. /// - protected readonly WorkingBeatmap WorkingBeatmap; + public readonly WorkingBeatmap WorkingBeatmap; public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); From 1427c9f57611eb1318b24529488825f6c9a57e32 Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sat, 26 Jan 2019 13:11:08 +0800 Subject: [PATCH 02/62] trim whitespaces --- osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs | 1 - osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs | 1 - osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs | 1 - osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs | 1 - osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs | 3 +-- osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs | 1 - 8 files changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs index b442358bc3..c423d0db69 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs @@ -6,6 +6,5 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModWindDown : ModWindDown { - } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs index 351ca56175..a5dde65fb9 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs @@ -6,6 +6,5 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModWindUp : ModWindUp { - } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs index 05272d8620..ee868ef4b7 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs @@ -6,6 +6,5 @@ namespace osu.Game.Rulesets.Mania.Mods { public class ManiaModWindDown : ModWindDown { - } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs index d9e663c977..d31e086fea 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs @@ -6,6 +6,5 @@ namespace osu.Game.Rulesets.Mania.Mods { public class ManiaModWindUp : ModWindUp { - } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs index 71035ad8e4..3254e0205b 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs @@ -6,6 +6,5 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModWindDown : ModWindDown { - } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs index 6eb4bdf703..bacf92b4b1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs @@ -6,6 +6,5 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModWindUp : ModWindUp { - } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs index 2a59c994b0..88e97524e6 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs @@ -5,7 +5,6 @@ using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModWindDown : ModWindDown - { - + { } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs index 7aee771ce9..628ba1348a 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs @@ -6,6 +6,5 @@ namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModWindUp : ModWindUp { - } } \ No newline at end of file From d76681aa825ac01d17a45c393f09163ce3c3dce3 Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sat, 26 Jan 2019 13:39:23 +0800 Subject: [PATCH 03/62] use IApplicableToBeatmap instead of IApplicableToRulesetContainer --- osu.Game/Rulesets/Mods/ModWindUp.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index 5deeff842b..d0cc9b419e 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -9,6 +9,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Mods { @@ -24,10 +25,10 @@ namespace osu.Game.Rulesets.Mods public abstract double AppendRate { get; } } - public class ModWindUp : ModWindUp, IUpdatableByPlayfield, IApplicableToClock, IApplicableToRulesetContainer + public abstract class ModWindUp : ModWindUp, IUpdatableByPlayfield, IApplicableToClock, IApplicableToBeatmap where T : HitObject { - private Track Track; + private double LastObjectEndTime; private IAdjustableClock Clock; private IHasPitchAdjust ClockAdjust; public override double AppendRate => 0.5; @@ -38,14 +39,15 @@ namespace osu.Game.Rulesets.Mods ClockAdjust = clock as IHasPitchAdjust; } - public virtual void ApplyToRulesetContainer(RulesetContainer ruleset) + public virtual void ApplyToBeatmap(Beatmap beatmap) { - Track = ruleset.WorkingBeatmap.Track; + HitObject LastObject = beatmap.HitObjects[beatmap.HitObjects.Count - 1]; + LastObjectEndTime = (LastObject as IHasEndTime)?.EndTime ?? LastObject?.StartTime ?? 0; } public virtual void Update(Playfield playfield) { - double newRate = 1 + (AppendRate * (Track.CurrentTime / Track.Length)); + double newRate = 1 + (AppendRate * (Clock.CurrentTime / LastObjectEndTime)); Clock.Rate = newRate; ClockAdjust.PitchAdjust = newRate; } From 39072376dd03a2f49339e943de7bfe8f9c073574 Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sat, 26 Jan 2019 13:40:41 +0800 Subject: [PATCH 04/62] revert WorkingBeatmap back to protected --- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index dfcd2f7602..0d020238aa 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -215,7 +215,7 @@ namespace osu.Game.Rulesets.UI /// /// The this was created with. /// - public readonly WorkingBeatmap WorkingBeatmap; + protected readonly WorkingBeatmap WorkingBeatmap; public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); From 73dbf5712d3eb5bb45047a8ba3031d40143d109c Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sat, 26 Jan 2019 13:43:27 +0800 Subject: [PATCH 05/62] add license headers --- osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs | 3 +++ osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs | 3 +++ osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs | 3 +++ osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs | 3 +++ osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs | 3 +++ osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs | 3 +++ osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs | 3 +++ osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs | 3 +++ osu.Game/Rulesets/Mods/ModWindDown.cs | 3 +++ osu.Game/Rulesets/Mods/ModWindUp.cs | 3 +++ 10 files changed, 30 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs index c423d0db69..535cc1c290 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs index a5dde65fb9..3293840e92 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs index ee868ef4b7..3ecb8f5f23 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mania.Objects; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs index d31e086fea..f482fe0641 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mania.Objects; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs index 3254e0205b..1a6abd5a8d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs index bacf92b4b1..16ee9c0ed1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs index 88e97524e6..6d83f428cf 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Objects; diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs index 628ba1348a..5a9dfb8348 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Objects; diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index 9fc65839fd..43765865ba 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using osu.Game.Graphics; using osu.Game.Rulesets.Objects; diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index d0cc9b419e..d1b9f6dbf7 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -1,3 +1,6 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + using System; using System.Collections.Generic; using osu.Framework.Audio; From d920ee67ee1f6269ecc957edd834942407c013de Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sat, 26 Jan 2019 13:47:33 +0800 Subject: [PATCH 06/62] forgot last whitespace --- osu.Game/Rulesets/Mods/ModWindDown.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index 43765865ba..e590e06ed6 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -15,5 +15,4 @@ namespace osu.Game.Rulesets.Mods public override FontAwesome Icon => FontAwesome.fa_chevron_circle_down; public override double AppendRate => -0.25; } - } \ No newline at end of file From 0f8c5bcbd7c8705087a43dde93bcb9bbd8e0e6e9 Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sat, 26 Jan 2019 13:50:27 +0800 Subject: [PATCH 07/62] actually the last whitespace --- osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs index 6d83f428cf..6a56ed1917 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs @@ -8,6 +8,6 @@ using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModWindDown : ModWindDown - { + { } } \ No newline at end of file From 03e57d0423fa25fce086af404a8304b40ec6347a Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sat, 26 Jan 2019 20:15:19 +0800 Subject: [PATCH 08/62] fix codefactor warnings and derive ModWindUp and ModWindDown to ModTimeRamp --- .../Mods/CatchModWindDown.cs | 1 - .../Mods/CatchModWindUp.cs | 1 - .../Mods/ManiaModWindDown.cs | 1 - .../Mods/ManiaModWindUp.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs | 1 - .../Mods/TaikoModWindDown.cs | 1 - .../Mods/TaikoModWindUp.cs | 1 - osu.Game/Rulesets/Mods/ModDoubleTime.cs | 2 +- osu.Game/Rulesets/Mods/ModHalfTime.cs | 2 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 46 ++++++++++++++++++ osu.Game/Rulesets/Mods/ModWindDown.cs | 5 +- osu.Game/Rulesets/Mods/ModWindUp.cs | 47 ++----------------- 13 files changed, 55 insertions(+), 55 deletions(-) create mode 100644 osu.Game/Rulesets/Mods/ModTimeRamp.cs diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs index 535cc1c290..95aa7c814c 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs index 3293840e92..1c447d4c8b 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs index 3ecb8f5f23..39dae4502c 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mania.Objects; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs index f482fe0641..6ad0693910 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mania.Objects; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs index 1a6abd5a8d..200fe54692 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs index 16ee9c0ed1..884f3fa716 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs index 6a56ed1917..566e39049a 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Objects; diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs index 5a9dfb8348..ea980c1212 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Objects; diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index d87fb5de23..e59654c60d 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mods public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Zoooooooooom..."; public override bool Ranked => true; - public override Type[] IncompatibleMods => new[] { typeof(ModHalfTime), typeof(ModWindUp) }; + public override Type[] IncompatibleMods => new[] { typeof(ModHalfTime), typeof(ModTimeRamp) }; public virtual void ApplyToClock(IAdjustableClock clock) { diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 0b421431d3..07cceb6f49 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mods public override ModType Type => ModType.DifficultyReduction; public override string Description => "Less zoom..."; public override bool Ranked => true; - public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime), typeof(ModWindUp) }; + public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime), typeof(ModTimeRamp) }; public virtual void ApplyToClock(IAdjustableClock clock) { diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs new file mode 100644 index 0000000000..5941be20c9 --- /dev/null +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Audio; +using osu.Framework.Timing; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; + +namespace osu.Game.Rulesets.Mods +{ + public abstract class ModTimeRamp : Mod + { + public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime), typeof(ModHalfTime) }; + public abstract double AppendRate { get; } + } + + public abstract class ModTimeRamp : ModTimeRamp, IUpdatableByPlayfield, IApplicableToClock, IApplicableToBeatmap + where T : HitObject + { + private double lastObjectEndTime; + private IAdjustableClock clock; + private IHasPitchAdjust pitchAdjust; + + public virtual void ApplyToClock(IAdjustableClock clk) + { + clock = clk; + pitchAdjust = clk as IHasPitchAdjust; + } + + public virtual void ApplyToBeatmap(Beatmap beatmap) + { + HitObject lastObject = beatmap.HitObjects[beatmap.HitObjects.Count - 1]; + lastObjectEndTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; + } + + public virtual void Update(Playfield playfield) + { + double newRate = 1 + (AppendRate * (clock.CurrentTime / lastObjectEndTime)); + clock.Rate = newRate; + pitchAdjust.PitchAdjust = newRate; + } + } +} \ No newline at end of file diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index e590e06ed6..474a1d4551 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -6,13 +6,14 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mods { - public class ModWindDown : ModWindUp + public class ModWindDown : ModTimeRamp where T : HitObject { public override string Name => "Wind Down"; public override string Acronym => "WD"; - public override string Description => "Slow down."; + public override string Description => "Cool down."; public override FontAwesome Icon => FontAwesome.fa_chevron_circle_down; + public override double ScoreMultiplier => 1.0; public override double AppendRate => -0.25; } } \ No newline at end of file diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index d1b9f6dbf7..6b41cd565c 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -1,58 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using System.Collections.Generic; -using osu.Framework.Audio; -using osu.Framework.Audio.Track; -using osu.Framework.Configuration; -using osu.Framework.Timing; -using osu.Framework.Graphics; -using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Mods { - public abstract class ModWindUp : Mod + public class ModWindUp : ModTimeRamp + where T : HitObject { public override string Name => "Wind Up"; public override string Acronym => "WU"; - public override ModType Type => ModType.Fun; - public override FontAwesome Icon => FontAwesome.fa_chevron_circle_up; public override string Description => "Crank it up!"; - public override double ScoreMultiplier => 1; - public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime), typeof(ModHalfTime) }; - public abstract double AppendRate { get; } - } - - public abstract class ModWindUp : ModWindUp, IUpdatableByPlayfield, IApplicableToClock, IApplicableToBeatmap - where T : HitObject - { - private double LastObjectEndTime; - private IAdjustableClock Clock; - private IHasPitchAdjust ClockAdjust; + public override FontAwesome Icon => FontAwesome.fa_chevron_circle_up; + public override double ScoreMultiplier => 1.0; public override double AppendRate => 0.5; - - public virtual void ApplyToClock(IAdjustableClock clock) - { - Clock = clock; - ClockAdjust = clock as IHasPitchAdjust; - } - - public virtual void ApplyToBeatmap(Beatmap beatmap) - { - HitObject LastObject = beatmap.HitObjects[beatmap.HitObjects.Count - 1]; - LastObjectEndTime = (LastObject as IHasEndTime)?.EndTime ?? LastObject?.StartTime ?? 0; - } - - public virtual void Update(Playfield playfield) - { - double newRate = 1 + (AppendRate * (Clock.CurrentTime / LastObjectEndTime)); - Clock.Rate = newRate; - ClockAdjust.PitchAdjust = newRate; - } } } \ No newline at end of file From bf8360636aa530816d841e34799112263f7fbf35 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 1 Mar 2019 13:01:52 +0900 Subject: [PATCH 09/62] Adjust drawnodes to use the new shared data structure --- .../UI/Cursor/CursorTrail.cs | 28 +++++++++---------- osu.Game/Graphics/Backgrounds/Triangles.cs | 21 +++++++------- osu.Game/Screens/Menu/LogoVisualisation.cs | 21 +++++++------- 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs index 0f8a0ce1ae..57c46f4379 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs @@ -35,7 +35,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor public override bool IsPresent => true; - private readonly TrailDrawNodeSharedData trailDrawNodeSharedData = new TrailDrawNodeSharedData(); private const int max_sprites = 2048; private readonly TrailPart[] parts = new TrailPart[max_sprites]; @@ -55,7 +54,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor tNode.Texture = texture; tNode.Size = size; tNode.Time = time; - tNode.Shared = trailDrawNodeSharedData; for (int i = 0; i < parts.Length; ++i) if (parts[i].InvalidationID > tNode.Parts[i].InvalidationID) @@ -167,22 +165,18 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor public bool WasUpdated; } - private class TrailDrawNodeSharedData - { - public VertexBuffer VertexBuffer; - } - private class TrailDrawNode : DrawNode { public Shader Shader; public Texture Texture; public float Time; - public TrailDrawNodeSharedData Shared; public readonly TrailPart[] Parts = new TrailPart[max_sprites]; public Vector2 Size; + private readonly VertexBuffer vertexBuffer = new QuadVertexBuffer(max_sprites, BufferUsageHint.DynamicDraw); + public TrailDrawNode() { for (int i = 0; i < max_sprites; i++) @@ -194,9 +188,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor public override void Draw(Action vertexAction) { - if (Shared.VertexBuffer == null) - Shared.VertexBuffer = new QuadVertexBuffer(max_sprites, BufferUsageHint.DynamicDraw); - Shader.GetUniform("g_FadeClock").UpdateValue(ref Time); int updateStart = -1, updateEnd = 0; @@ -218,7 +209,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor new Quad(pos.X - Size.X / 2, pos.Y - Size.Y / 2, Size.X, Size.Y), DrawColourInfo.Colour, null, - v => Shared.VertexBuffer.Vertices[end++] = new TexturedTrailVertex + v => vertexBuffer.Vertices[end++] = new TexturedTrailVertex { Position = v.Position, TexturePosition = v.TexturePosition, @@ -230,24 +221,31 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor } else if (updateStart != -1) { - Shared.VertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4); + vertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4); updateStart = -1; } } // Update all remaining vertices that have been changed. if (updateStart != -1) - Shared.VertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4); + vertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4); base.Draw(vertexAction); Shader.Bind(); Texture.TextureGL.Bind(); - Shared.VertexBuffer.Draw(); + vertexBuffer.Draw(); Shader.Unbind(); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + vertexBuffer.Dispose(); + } } [StructLayout(LayoutKind.Sequential)] diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index ebd9db786f..3582a3635f 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -180,8 +180,6 @@ namespace osu.Game.Graphics.Backgrounds protected override DrawNode CreateDrawNode() => new TrianglesDrawNode(); - private readonly TrianglesDrawNodeSharedData sharedData = new TrianglesDrawNodeSharedData(); - protected override void ApplyDrawNode(DrawNode node) { base.ApplyDrawNode(node); @@ -191,27 +189,21 @@ namespace osu.Game.Graphics.Backgrounds trianglesNode.Shader = shader; trianglesNode.Texture = texture; trianglesNode.Size = DrawSize; - trianglesNode.Shared = sharedData; trianglesNode.Parts.Clear(); trianglesNode.Parts.AddRange(parts); } - private class TrianglesDrawNodeSharedData - { - public readonly LinearBatch VertexBatch = new LinearBatch(100 * 3, 10, PrimitiveType.Triangles); - } - private class TrianglesDrawNode : DrawNode { public Shader Shader; public Texture Texture; - public TrianglesDrawNodeSharedData Shared; - public readonly List Parts = new List(); public Vector2 Size; + private readonly LinearBatch vertexBatch = new LinearBatch(100 * 3, 10, PrimitiveType.Triangles); + public override void Draw(Action vertexAction) { base.Draw(vertexAction); @@ -239,12 +231,19 @@ namespace osu.Game.Graphics.Backgrounds triangle, colourInfo, null, - Shared.VertexBatch.AddAction, + vertexBatch.AddAction, Vector2.Divide(localInflationAmount, size)); } Shader.Unbind(); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + vertexBatch.Dispose(); + } } protected struct TriangleParticle : IComparable diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index e930f924be..fdf13091be 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -131,8 +131,6 @@ namespace osu.Game.Screens.Menu protected override DrawNode CreateDrawNode() => new VisualisationDrawNode(); - private readonly VisualiserSharedData sharedData = new VisualiserSharedData(); - protected override void ApplyDrawNode(DrawNode node) { base.ApplyDrawNode(node); @@ -142,29 +140,23 @@ namespace osu.Game.Screens.Menu visNode.Shader = shader; visNode.Texture = texture; visNode.Size = DrawSize.X; - visNode.Shared = sharedData; visNode.Colour = AccentColour; visNode.AudioData = frequencyAmplitudes; } - private class VisualiserSharedData - { - public readonly QuadBatch VertexBatch = new QuadBatch(100, 10); - } - private class VisualisationDrawNode : DrawNode { public Shader Shader; public Texture Texture; - public VisualiserSharedData Shared; - //Asuming the logo is a circle, we don't need a second dimension. public float Size; public Color4 Colour; public float[] AudioData; + private readonly QuadBatch vertexBatch = new QuadBatch(100, 10); + public override void Draw(Action vertexAction) { base.Draw(vertexAction); @@ -209,7 +201,7 @@ namespace osu.Game.Screens.Menu rectangle, colourInfo, null, - Shared.VertexBatch.AddAction, + vertexBatch.AddAction, //barSize by itself will make it smooth more in the X axis than in the Y axis, this reverts that. Vector2.Divide(inflation, barSize.Yx)); } @@ -218,6 +210,13 @@ namespace osu.Game.Screens.Menu Shader.Unbind(); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + vertexBatch.Dispose(); + } } } } From a1a8246c05cb920e14a35f0fbba9df573bbe6233 Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sun, 3 Mar 2019 16:30:08 +0800 Subject: [PATCH 10/62] trim whitespace --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 6cc22131e0..c10727f5cf 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -39,7 +39,6 @@ namespace osu.Game.Rulesets.Mods public virtual void Update(Playfield playfield) { double newRate; - if (1 + AppendRate < 1) newRate = Math.Max(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))); else From b83d44c3167c518e64b8f1f8860ebda19bdaebcd Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sun, 3 Mar 2019 16:50:31 +0800 Subject: [PATCH 11/62] use ternary operator instead --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index c10727f5cf..194226b4b7 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -38,12 +38,8 @@ namespace osu.Game.Rulesets.Mods public virtual void Update(Playfield playfield) { - double newRate; - if (1 + AppendRate < 1) - newRate = Math.Max(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))); - else - newRate = Math.Min(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))); - + double newRate = 1 + AppendRate < 1 ? Math.Max(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))) : + Math.Min(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))); clock.Rate = newRate; pitchAdjust.PitchAdjust = newRate; } From c271a3a7818d1b04a635433fdb5dce0c348401cb Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Mon, 4 Mar 2019 17:36:44 +0800 Subject: [PATCH 12/62] remove ruleset specific mods --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 3 ++- osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs | 12 ------------ osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs | 12 ------------ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 3 ++- osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs | 12 ------------ osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs | 12 ------------ osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs | 12 ------------ osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs | 12 ------------ osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 ++- osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs | 12 ------------ osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs | 12 ------------ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 3 ++- 12 files changed, 8 insertions(+), 100 deletions(-) delete mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs delete mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs delete mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs delete mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs delete mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs delete mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs delete mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs delete mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 62892a1bdf..af8206d95a 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.UI; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; @@ -102,7 +103,7 @@ namespace osu.Game.Rulesets.Catch case ModType.Fun: return new Mod[] { - new MultiMod(new CatchModWindUp(), new CatchModWindDown()) + new MultiMod(new ModWindUp(), new ModWindDown()) }; default: return new Mod[] { }; diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs deleted file mode 100644 index 95aa7c814c..0000000000 --- a/osu.Game.Rulesets.Catch/Mods/CatchModWindDown.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Catch.Objects; - -namespace osu.Game.Rulesets.Catch.Mods -{ - public class CatchModWindDown : ModWindDown - { - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs b/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs deleted file mode 100644 index 1c447d4c8b..0000000000 --- a/osu.Game.Rulesets.Catch/Mods/CatchModWindUp.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Catch.Objects; - -namespace osu.Game.Rulesets.Catch.Mods -{ - public class CatchModWindUp : ModWindUp - { - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 8fcb15f640..2014417af9 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -12,6 +12,7 @@ using System.Linq; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; using osu.Game.Graphics; +using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; @@ -148,7 +149,7 @@ namespace osu.Game.Rulesets.Mania case ModType.Fun: return new Mod[] { - new MultiMod(new ManiaModWindUp(), new ManiaModWindDown()) + new MultiMod(new ModWindUp(), new ModWindDown()) }; default: return new Mod[] { }; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs deleted file mode 100644 index 39dae4502c..0000000000 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModWindDown.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Mania.Objects; - -namespace osu.Game.Rulesets.Mania.Mods -{ - public class ManiaModWindDown : ModWindDown - { - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs deleted file mode 100644 index 6ad0693910..0000000000 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModWindUp.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Mania.Objects; - -namespace osu.Game.Rulesets.Mania.Mods -{ - public class ManiaModWindUp : ModWindUp - { - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs deleted file mode 100644 index 200fe54692..0000000000 --- a/osu.Game.Rulesets.Osu/Mods/OsuModWindDown.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Objects; - -namespace osu.Game.Rulesets.Osu.Mods -{ - public class OsuModWindDown : ModWindDown - { - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs deleted file mode 100644 index 884f3fa716..0000000000 --- a/osu.Game.Rulesets.Osu/Mods/OsuModWindUp.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Objects; - -namespace osu.Game.Rulesets.Osu.Mods -{ - public class OsuModWindUp : ModWindUp - { - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index b9a0d61b22..bc6a74c17d 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -13,6 +13,7 @@ using osu.Game.Overlays.Settings; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; @@ -126,7 +127,7 @@ namespace osu.Game.Rulesets.Osu new OsuModTransform(), new OsuModWiggle(), new OsuModGrow(), - new MultiMod(new OsuModWindUp(), new OsuModWindDown()), + new MultiMod(new ModWindUp(), new ModWindDown()), }; default: return new Mod[] { }; diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs deleted file mode 100644 index 566e39049a..0000000000 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindDown.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Taiko.Objects; - -namespace osu.Game.Rulesets.Taiko.Mods -{ - public class TaikoModWindDown : ModWindDown - { - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs deleted file mode 100644 index ea980c1212..0000000000 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModWindUp.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Taiko.Objects; - -namespace osu.Game.Rulesets.Taiko.Mods -{ - public class TaikoModWindUp : ModWindUp - { - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index d9c7703ebf..08a56488aa 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Replays.Types; +using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Replays; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Difficulty; @@ -102,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko case ModType.Fun: return new Mod[] { - new MultiMod(new TaikoModWindUp(), new TaikoModWindDown()) + new MultiMod(new ModWindUp(), new ModWindDown()) }; default: return new Mod[] { }; From 86e861ddeb38e3c6b9ac45b435a0cae003455119 Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Mon, 4 Mar 2019 17:39:13 +0800 Subject: [PATCH 13/62] update mod descriptions --- osu.Game/Rulesets/Mods/ModWindDown.cs | 2 +- osu.Game/Rulesets/Mods/ModWindUp.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index 474a1d4551..4054cd10a5 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mods { public override string Name => "Wind Down"; public override string Acronym => "WD"; - public override string Description => "Cool down."; + public override string Description => "Sloooow doooown..."; public override FontAwesome Icon => FontAwesome.fa_chevron_circle_down; public override double ScoreMultiplier => 1.0; public override double AppendRate => -0.25; diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index 6b41cd565c..cdae60fcf1 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mods { public override string Name => "Wind Up"; public override string Acronym => "WU"; - public override string Description => "Crank it up!"; + public override string Description => "Can you keep up?"; public override FontAwesome Icon => FontAwesome.fa_chevron_circle_up; public override double ScoreMultiplier => 1.0; public override double AppendRate => 0.5; From 74a23edaf78d4703ab36269cbbc0b998904d8e61 Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Mon, 4 Mar 2019 17:48:51 +0800 Subject: [PATCH 14/62] no longer adjust the clock rate --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 194226b4b7..2d97f2a237 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -28,6 +28,7 @@ namespace osu.Game.Rulesets.Mods { clock = clk; pitchAdjust = clk as IHasPitchAdjust; + pitchAdjust.PitchAdjust = 1.0 + AppendRate; } public virtual void ApplyToBeatmap(Beatmap beatmap) @@ -40,7 +41,6 @@ namespace osu.Game.Rulesets.Mods { double newRate = 1 + AppendRate < 1 ? Math.Max(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))) : Math.Min(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))); - clock.Rate = newRate; pitchAdjust.PitchAdjust = newRate; } } From aecbc31ffa23b0f343d388bfa2fd193953ee7042 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 5 Mar 2019 12:08:14 +0900 Subject: [PATCH 15/62] Use BeatmapSetCoverType.List for lobby listing --- .../Drawables/UpdateableBeatmapBackgroundSprite.cs | 7 +++++-- .../Multi/Components/MultiplayerListSprite.cs | 13 +++++++++++++ .../Screens/Multi/Lounge/Components/DrawableRoom.cs | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Screens/Multi/Components/MultiplayerListSprite.cs diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 6fa7d47683..2414318db7 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -18,9 +18,12 @@ namespace osu.Game.Beatmaps.Drawables [Resolved] private BeatmapManager beatmaps { get; set; } - public UpdateableBeatmapBackgroundSprite() + private readonly BeatmapSetCoverType beatmapSetCoverType; + + public UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) { Beatmap.BindValueChanged(b => Model = b.NewValue); + this.beatmapSetCoverType = beatmapSetCoverType; } protected override Drawable CreateDrawable(BeatmapInfo model) @@ -32,7 +35,7 @@ namespace osu.Game.Beatmaps.Drawables var localBeatmap = beatmaps.GetWorkingBeatmap(model); if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null) - drawable = new BeatmapSetCover(model.BeatmapSet); + drawable = new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); else drawable = new BeatmapBackgroundSprite(localBeatmap); diff --git a/osu.Game/Screens/Multi/Components/MultiplayerListSprite.cs b/osu.Game/Screens/Multi/Components/MultiplayerListSprite.cs new file mode 100644 index 0000000000..42448f4885 --- /dev/null +++ b/osu.Game/Screens/Multi/Components/MultiplayerListSprite.cs @@ -0,0 +1,13 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Beatmaps.Drawables; + +namespace osu.Game.Screens.Multi.Components +{ + public class MultiplayerListSprite : MultiplayerBackgroundSprite + { + protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType.List) { RelativeSizeAxes = Axes.Both }; + } +} diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index e41238a7ff..eae693a089 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -137,7 +137,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Width = cover_width, Masking = true, Margin = new MarginPadding { Left = side_strip_width }, - Child = new MultiplayerBackgroundSprite { RelativeSizeAxes = Axes.Both } + Child = new MultiplayerListSprite { RelativeSizeAxes = Axes.Both } }, new Container { From 7c53c7b602134ed40471bbed9e7616aff075af65 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 5 Mar 2019 15:33:39 +0900 Subject: [PATCH 16/62] Remove local background logic --- .../Drawables/UpdateableBeatmapBackgroundSprite.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 2414318db7..db98c8a9a9 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Beatmaps.Drawables { /// - /// Display a baetmap background from a local source, but fallback to online source if not available. + /// Display a beatmap background from an online source /// public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable { @@ -30,14 +30,10 @@ namespace osu.Game.Beatmaps.Drawables { return new DelayedLoadUnloadWrapper(() => { - Drawable drawable; + if (model?.BeatmapSet?.OnlineInfo == null) + return null; - var localBeatmap = beatmaps.GetWorkingBeatmap(model); - - if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null) - drawable = new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); - else - drawable = new BeatmapBackgroundSprite(localBeatmap); + Drawable drawable = new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); drawable.RelativeSizeAxes = Axes.Both; drawable.Anchor = Anchor.Centre; From fc62877fdcf30c6fbfd5c61f601e7fc0afbb8a3d Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 5 Mar 2019 15:51:43 +0900 Subject: [PATCH 17/62] Fall back to default background --- .../Drawables/UpdateableBeatmapBackgroundSprite.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index db98c8a9a9..ef68c667cd 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -30,10 +30,15 @@ namespace osu.Game.Beatmaps.Drawables { return new DelayedLoadUnloadWrapper(() => { - if (model?.BeatmapSet?.OnlineInfo == null) - return null; + Drawable drawable; - Drawable drawable = new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); + if (model?.BeatmapSet?.OnlineInfo != null) + drawable = new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); + else + { + // Use the default background if somehow an online set does not exist. + drawable = new BeatmapBackgroundSprite(beatmaps.GetWorkingBeatmap(null)); + } drawable.RelativeSizeAxes = Axes.Both; drawable.Anchor = Anchor.Centre; From 11e353c152e9147dbd0315aa3ef4d8283825f1ab Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 5 Mar 2019 15:55:37 +0900 Subject: [PATCH 18/62] Use local class instead of having a separate file --- .../Multi/Components/MultiplayerListSprite.cs | 13 ------------- .../Screens/Multi/Lounge/Components/DrawableRoom.cs | 6 ++++++ 2 files changed, 6 insertions(+), 13 deletions(-) delete mode 100644 osu.Game/Screens/Multi/Components/MultiplayerListSprite.cs diff --git a/osu.Game/Screens/Multi/Components/MultiplayerListSprite.cs b/osu.Game/Screens/Multi/Components/MultiplayerListSprite.cs deleted file mode 100644 index 42448f4885..0000000000 --- a/osu.Game/Screens/Multi/Components/MultiplayerListSprite.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Game.Beatmaps.Drawables; - -namespace osu.Game.Screens.Multi.Components -{ - public class MultiplayerListSprite : MultiplayerBackgroundSprite - { - protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType.List) { RelativeSizeAxes = Axes.Both }; - } -} diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index eae693a089..76f2b056c7 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -202,6 +203,11 @@ namespace osu.Game.Screens.Multi.Lounge.Components this.FadeInFromZero(transition_duration); } + private class MultiplayerListSprite : MultiplayerBackgroundSprite + { + protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType.List) { RelativeSizeAxes = Axes.Both }; + } + private class RoomName : OsuSpriteText { [Resolved(typeof(Room), nameof(Online.Multiplayer.Room.Name))] From 166a8c8bbb963ef1b1e3254da66b3857152d4dc2 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 5 Mar 2019 16:41:59 +0900 Subject: [PATCH 19/62] Add back fallback behavior for match creation --- osu.Game/Beatmaps/BeatmapManager.cs | 3 +++ .../Drawables/UpdateableBeatmapBackgroundSprite.cs | 14 ++++++++++++-- .../Multi/Lounge/Components/DrawableRoom.cs | 2 +- osu.Game/Screens/Multi/Match/Components/Header.cs | 7 ++++++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 2b559d5912..8a66301a30 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -263,6 +263,9 @@ namespace osu.Game.Beatmaps if (beatmapInfo.Metadata == null) beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata; + var info = beatmapInfo; + beatmapInfo = QueryBeatmap(p => info.OnlineBeatmapID == p.OnlineBeatmapID) ?? beatmapInfo; + WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(Files.Store, new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager); previous?.TransferTo(working); diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index ef68c667cd..d29560b4ac 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -20,10 +20,13 @@ namespace osu.Game.Beatmaps.Drawables private readonly BeatmapSetCoverType beatmapSetCoverType; - public UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) + private readonly bool fallback; + + public UpdateableBeatmapBackgroundSprite(bool fallback = false, BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) { Beatmap.BindValueChanged(b => Model = b.NewValue); this.beatmapSetCoverType = beatmapSetCoverType; + this.fallback = fallback; } protected override Drawable CreateDrawable(BeatmapInfo model) @@ -32,11 +35,18 @@ namespace osu.Game.Beatmaps.Drawables { Drawable drawable; + var localBeatmap = beatmaps.GetWorkingBeatmap(model); + if (model?.BeatmapSet?.OnlineInfo != null) drawable = new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); + else if (fallback && localBeatmap.BeatmapInfo.ID != 0) + { + // Fall back to local background if one exists + drawable = new BeatmapBackgroundSprite(beatmaps.GetWorkingBeatmap(model)); + } else { - // Use the default background if somehow an online set does not exist. + // Use the default background if somehow an online set does not exist and we don't have a local copy. drawable = new BeatmapBackgroundSprite(beatmaps.GetWorkingBeatmap(null)); } diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index 76f2b056c7..6a21e8f333 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -205,7 +205,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components private class MultiplayerListSprite : MultiplayerBackgroundSprite { - protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType.List) { RelativeSizeAxes = Axes.Both }; + protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(beatmapSetCoverType: BeatmapSetCoverType.List) { RelativeSizeAxes = Axes.Both }; } private class RoomName : OsuSpriteText diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 6a6a1f274c..dafbb77bc6 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -132,10 +132,15 @@ namespace osu.Game.Screens.Multi.Match.Components private class HeaderBackgroundSprite : MultiplayerBackgroundSprite { - protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both }; + protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite(true) { RelativeSizeAxes = Axes.Both }; private class BackgroundSprite : UpdateableBeatmapBackgroundSprite { + public BackgroundSprite(bool fallback = false, BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) + : base(fallback, beatmapSetCoverType) + { + } + protected override double FadeDuration => 200; } } From 52558c5cf664ec03fe3460b9957d0e5341360d24 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 5 Mar 2019 16:59:02 +0900 Subject: [PATCH 20/62] Fix metadata potentially being null --- osu.Game/Beatmaps/BeatmapManager.cs | 6 +++--- .../Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 8a66301a30..94b7f00333 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -260,12 +260,12 @@ namespace osu.Game.Beatmaps if (beatmapInfo?.BeatmapSet == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo) return DefaultBeatmap; - if (beatmapInfo.Metadata == null) - beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata; - var info = beatmapInfo; beatmapInfo = QueryBeatmap(p => info.OnlineBeatmapID == p.OnlineBeatmapID) ?? beatmapInfo; + if (beatmapInfo.Metadata == null) + beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata; + WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(Files.Store, new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager); previous?.TransferTo(working); diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index d29560b4ac..2d19afd98d 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -42,7 +42,7 @@ namespace osu.Game.Beatmaps.Drawables else if (fallback && localBeatmap.BeatmapInfo.ID != 0) { // Fall back to local background if one exists - drawable = new BeatmapBackgroundSprite(beatmaps.GetWorkingBeatmap(model)); + drawable = new BeatmapBackgroundSprite(localBeatmap); } else { From fc0b297232b46885454e65af4c42c518bb428b08 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Mar 2019 18:06:24 +0900 Subject: [PATCH 21/62] Fix menu cursor not displaying outside of gameplay scaling area --- osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs | 6 +++--- .../{GameplayCursor.cs => GameplayCursorContainer.cs} | 4 ++-- osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs | 2 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 10 ++++++++-- osu.Game/Screens/Play/Player.cs | 7 +------ 5 files changed, 15 insertions(+), 14 deletions(-) rename osu.Game.Rulesets.Osu/UI/Cursor/{GameplayCursor.cs => GameplayCursorContainer.cs} (98%) diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs index 3d553c334f..5c1e775c01 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs @@ -16,18 +16,18 @@ namespace osu.Game.Rulesets.Osu.Tests [TestFixture] public class TestCaseGameplayCursor : OsuTestCase, IProvideCursor { - private GameplayCursor cursor; + private GameplayCursorContainer cursorContainer; public override IReadOnlyList RequiredTypes => new[] { typeof(CursorTrail) }; - public CursorContainer Cursor => cursor; + public CursorContainer Cursor => cursorContainer; public bool ProvidingUserCursor => true; [BackgroundDependencyLoader] private void load() { - Add(cursor = new GameplayCursor { RelativeSizeAxes = Axes.Both }); + Add(cursorContainer = new GameplayCursorContainer { RelativeSizeAxes = Axes.Both }); } } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs similarity index 98% rename from osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs rename to osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs index ef126cdf7d..ca8368155f 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.UI.Cursor { - public class GameplayCursor : CursorContainer, IKeyBindingHandler + public class GameplayCursorContainer : CursorContainer, IKeyBindingHandler { protected override Drawable CreateCursor() => new OsuCursor(); @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private readonly Container fadeContainer; - public GameplayCursor() + public GameplayCursorContainer() { InternalChild = fadeContainer = new Container { diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 85b72cbb5b..805bbfb4d4 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -60,6 +60,6 @@ namespace osu.Game.Rulesets.Osu.UI } } - protected override CursorContainer CreateCursor() => new GameplayCursor(); + protected override CursorContainer CreateCursor() => new GameplayCursorContainer(); } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 1c29cf4e2b..c9ad7bb5ec 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -16,7 +16,9 @@ using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; +using osu.Framework.Input.Events; using osu.Game.Configuration; +using osu.Game.Graphics.Cursor; using osu.Game.Input.Handlers; using osu.Game.Overlays; using osu.Game.Replays; @@ -32,7 +34,7 @@ namespace osu.Game.Rulesets.UI /// Should not be derived - derive instead. /// /// - public abstract class RulesetContainer : Container + public abstract class RulesetContainer : Container, IProvideCursor { /// /// The selected variant. @@ -77,7 +79,11 @@ namespace osu.Game.Rulesets.UI /// /// The cursor provided by this . May be null if no cursor is provided. /// - public readonly CursorContainer Cursor; + public CursorContainer Cursor { get; } + + public bool ProvidingUserCursor => Cursor != null && !HasReplayLoaded.Value; + + protected override bool OnHover(HoverEvent e) => true; // required for IProvideCursor public readonly Ruleset Ruleset; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index ee59df0e98..1518ee2f32 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -11,7 +11,6 @@ using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Framework.Screens; @@ -20,7 +19,6 @@ using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Cursor; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Rulesets; @@ -34,7 +32,7 @@ using osu.Game.Storyboards.Drawables; namespace osu.Game.Screens.Play { - public class Player : ScreenWithBeatmapBackground, IProvideCursor + public class Player : ScreenWithBeatmapBackground { protected override bool AllowBackButton => false; // handled by HoldForMenuButton @@ -59,9 +57,6 @@ namespace osu.Game.Screens.Play public int RestartCount; - public CursorContainer Cursor => RulesetContainer.Cursor; - public bool ProvidingUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded.Value; - private IAdjustableClock sourceClock; /// From 34b2553b95cc4c2ce980bb608bffc9cbcd58efdd Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 5 Mar 2019 18:59:25 +0900 Subject: [PATCH 22/62] Remove redundant boolean --- osu.Game/Beatmaps/BeatmapManager.cs | 3 --- .../Drawables/UpdateableBeatmapBackgroundSprite.cs | 9 +++------ .../Multi/Components/MultiplayerBackgroundSprite.cs | 9 ++++++++- osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs | 7 +------ osu.Game/Screens/Multi/Match/Components/Header.cs | 7 +------ 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 94b7f00333..2b559d5912 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -260,9 +260,6 @@ namespace osu.Game.Beatmaps if (beatmapInfo?.BeatmapSet == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo) return DefaultBeatmap; - var info = beatmapInfo; - beatmapInfo = QueryBeatmap(p => info.OnlineBeatmapID == p.OnlineBeatmapID) ?? beatmapInfo; - if (beatmapInfo.Metadata == null) beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata; diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 2d19afd98d..5c81779f83 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Beatmaps.Drawables { /// - /// Display a beatmap background from an online source + /// Display a baetmap background from a local source, but fallback to online source if not available. /// public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable { @@ -20,13 +20,10 @@ namespace osu.Game.Beatmaps.Drawables private readonly BeatmapSetCoverType beatmapSetCoverType; - private readonly bool fallback; - - public UpdateableBeatmapBackgroundSprite(bool fallback = false, BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) + public UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) { Beatmap.BindValueChanged(b => Model = b.NewValue); this.beatmapSetCoverType = beatmapSetCoverType; - this.fallback = fallback; } protected override Drawable CreateDrawable(BeatmapInfo model) @@ -39,7 +36,7 @@ namespace osu.Game.Beatmaps.Drawables if (model?.BeatmapSet?.OnlineInfo != null) drawable = new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); - else if (fallback && localBeatmap.BeatmapInfo.ID != 0) + else if (localBeatmap.BeatmapInfo.ID != 0) { // Fall back to local background if one exists drawable = new BeatmapBackgroundSprite(localBeatmap); diff --git a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs index 512f79942d..968fa6e72e 100644 --- a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs +++ b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs @@ -9,6 +9,13 @@ namespace osu.Game.Screens.Multi.Components { public class MultiplayerBackgroundSprite : MultiplayerComposite { + private readonly BeatmapSetCoverType beatmapSetCoverType; + + public MultiplayerBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) + { + this.beatmapSetCoverType = beatmapSetCoverType; + } + [BackgroundDependencyLoader] private void load() { @@ -19,6 +26,6 @@ namespace osu.Game.Screens.Multi.Components CurrentItem.BindValueChanged(item => sprite.Beatmap.Value = item.NewValue?.Beatmap, true); } - protected virtual UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both }; + protected virtual UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(beatmapSetCoverType) { RelativeSizeAxes = Axes.Both }; } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index 6a21e8f333..4bab68058f 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -138,7 +138,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Width = cover_width, Masking = true, Margin = new MarginPadding { Left = side_strip_width }, - Child = new MultiplayerListSprite { RelativeSizeAxes = Axes.Both } + Child = new MultiplayerBackgroundSprite(BeatmapSetCoverType.List) { RelativeSizeAxes = Axes.Both } }, new Container { @@ -203,11 +203,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components this.FadeInFromZero(transition_duration); } - private class MultiplayerListSprite : MultiplayerBackgroundSprite - { - protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(beatmapSetCoverType: BeatmapSetCoverType.List) { RelativeSizeAxes = Axes.Both }; - } - private class RoomName : OsuSpriteText { [Resolved(typeof(Room), nameof(Online.Multiplayer.Room.Name))] diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index dafbb77bc6..6a6a1f274c 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -132,15 +132,10 @@ namespace osu.Game.Screens.Multi.Match.Components private class HeaderBackgroundSprite : MultiplayerBackgroundSprite { - protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite(true) { RelativeSizeAxes = Axes.Both }; + protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both }; private class BackgroundSprite : UpdateableBeatmapBackgroundSprite { - public BackgroundSprite(bool fallback = false, BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) - : base(fallback, beatmapSetCoverType) - { - } - protected override double FadeDuration => 200; } } From 9441f8803307882711372ebc963918d4ed889c0b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Mar 2019 13:01:37 +0900 Subject: [PATCH 23/62] Use actual reference to default beatmap for fallback Co-Authored-By: nyquillerium --- .../Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 5c81779f83..012926fb0e 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps.Drawables else { // Use the default background if somehow an online set does not exist and we don't have a local copy. - drawable = new BeatmapBackgroundSprite(beatmaps.GetWorkingBeatmap(null)); + drawable = new BeatmapBackgroundSprite(beatmaps.DefaultBeatmap); } drawable.RelativeSizeAxes = Axes.Both; From 2300e59e917a27bb1182a1858282f5d1fc1f6849 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Mar 2019 14:14:41 +0900 Subject: [PATCH 24/62] Formatting and simplification --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 41 +++++++++++++++++++-------- osu.Game/Rulesets/Mods/ModWindDown.cs | 4 +-- osu.Game/Rulesets/Mods/ModWindUp.cs | 2 +- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 2d97f2a237..4a0ed0f9bb 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -2,46 +2,63 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Audio; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; +using osuTK; namespace osu.Game.Rulesets.Mods { public abstract class ModTimeRamp : Mod { public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime), typeof(ModHalfTime) }; - public abstract double AppendRate { get; } + + protected abstract double FinalRateAdjustment { get; } } public abstract class ModTimeRamp : ModTimeRamp, IUpdatableByPlayfield, IApplicableToClock, IApplicableToBeatmap where T : HitObject { - private double lastObjectEndTime; + private double finalRateTime; + + private double beginRampTime; + private IAdjustableClock clock; + private IHasPitchAdjust pitchAdjust; - public virtual void ApplyToClock(IAdjustableClock clk) + /// + /// The point in the beatmap at which the final ramping rate should be reached. + /// + private const double final_rate_progress = 0.75f; + + public virtual void ApplyToClock(IAdjustableClock clock) { - clock = clk; - pitchAdjust = clk as IHasPitchAdjust; - pitchAdjust.PitchAdjust = 1.0 + AppendRate; + this.clock = clock; + pitchAdjust = (IHasPitchAdjust)clock; + + // for preview purposes + pitchAdjust.PitchAdjust = 1.0 + FinalRateAdjustment; } public virtual void ApplyToBeatmap(Beatmap beatmap) { - HitObject lastObject = beatmap.HitObjects[beatmap.HitObjects.Count - 1]; - lastObjectEndTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; + HitObject lastObject = beatmap.HitObjects.LastOrDefault(); + + beginRampTime = beatmap.HitObjects.FirstOrDefault()?.StartTime ?? 0; + finalRateTime = final_rate_progress * ((lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0); } public virtual void Update(Playfield playfield) { - double newRate = 1 + AppendRate < 1 ? Math.Max(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))) : - Math.Min(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))); - pitchAdjust.PitchAdjust = newRate; + var absRate = Math.Abs(FinalRateAdjustment); + var adjustment = MathHelper.Clamp(absRate * ((clock.CurrentTime - beginRampTime) / finalRateTime), 0, absRate); + + pitchAdjust.PitchAdjust = 1 + Math.Sign(FinalRateAdjustment) * adjustment; } } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index 4054cd10a5..646c5c64e4 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Mods public override string Description => "Sloooow doooown..."; public override FontAwesome Icon => FontAwesome.fa_chevron_circle_down; public override double ScoreMultiplier => 1.0; - public override double AppendRate => -0.25; + protected override double FinalRateAdjustment => -0.25; } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index cdae60fcf1..9050b5591a 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Mods public override string Description => "Can you keep up?"; public override FontAwesome Icon => FontAwesome.fa_chevron_circle_up; public override double ScoreMultiplier => 1.0; - public override double AppendRate => 0.5; + protected override double FinalRateAdjustment => 0.5; } } \ No newline at end of file From 5411c630939b90fa601d8c79ee8da8613e355a6a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Mar 2019 18:06:24 +0900 Subject: [PATCH 25/62] Fix menu cursor not displaying outside of gameplay scaling area --- osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs | 6 +++--- .../{GameplayCursor.cs => GameplayCursorContainer.cs} | 4 ++-- osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs | 2 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 10 ++++++++-- osu.Game/Screens/Play/Player.cs | 7 +------ 5 files changed, 15 insertions(+), 14 deletions(-) rename osu.Game.Rulesets.Osu/UI/Cursor/{GameplayCursor.cs => GameplayCursorContainer.cs} (98%) diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs index 3d553c334f..5c1e775c01 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs @@ -16,18 +16,18 @@ namespace osu.Game.Rulesets.Osu.Tests [TestFixture] public class TestCaseGameplayCursor : OsuTestCase, IProvideCursor { - private GameplayCursor cursor; + private GameplayCursorContainer cursorContainer; public override IReadOnlyList RequiredTypes => new[] { typeof(CursorTrail) }; - public CursorContainer Cursor => cursor; + public CursorContainer Cursor => cursorContainer; public bool ProvidingUserCursor => true; [BackgroundDependencyLoader] private void load() { - Add(cursor = new GameplayCursor { RelativeSizeAxes = Axes.Both }); + Add(cursorContainer = new GameplayCursorContainer { RelativeSizeAxes = Axes.Both }); } } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs similarity index 98% rename from osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs rename to osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs index ef126cdf7d..ca8368155f 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.UI.Cursor { - public class GameplayCursor : CursorContainer, IKeyBindingHandler + public class GameplayCursorContainer : CursorContainer, IKeyBindingHandler { protected override Drawable CreateCursor() => new OsuCursor(); @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private readonly Container fadeContainer; - public GameplayCursor() + public GameplayCursorContainer() { InternalChild = fadeContainer = new Container { diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 85b72cbb5b..805bbfb4d4 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -60,6 +60,6 @@ namespace osu.Game.Rulesets.Osu.UI } } - protected override CursorContainer CreateCursor() => new GameplayCursor(); + protected override CursorContainer CreateCursor() => new GameplayCursorContainer(); } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 1c29cf4e2b..c9ad7bb5ec 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -16,7 +16,9 @@ using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; +using osu.Framework.Input.Events; using osu.Game.Configuration; +using osu.Game.Graphics.Cursor; using osu.Game.Input.Handlers; using osu.Game.Overlays; using osu.Game.Replays; @@ -32,7 +34,7 @@ namespace osu.Game.Rulesets.UI /// Should not be derived - derive instead. /// /// - public abstract class RulesetContainer : Container + public abstract class RulesetContainer : Container, IProvideCursor { /// /// The selected variant. @@ -77,7 +79,11 @@ namespace osu.Game.Rulesets.UI /// /// The cursor provided by this . May be null if no cursor is provided. /// - public readonly CursorContainer Cursor; + public CursorContainer Cursor { get; } + + public bool ProvidingUserCursor => Cursor != null && !HasReplayLoaded.Value; + + protected override bool OnHover(HoverEvent e) => true; // required for IProvideCursor public readonly Ruleset Ruleset; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 44707c74f5..0f4fa3e762 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -11,7 +11,6 @@ using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Framework.Screens; @@ -20,7 +19,6 @@ using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Cursor; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Rulesets; @@ -34,7 +32,7 @@ using osu.Game.Storyboards.Drawables; namespace osu.Game.Screens.Play { - public class Player : ScreenWithBeatmapBackground, IProvideCursor + public class Player : ScreenWithBeatmapBackground { protected override bool AllowBackButton => false; // handled by HoldForMenuButton @@ -59,9 +57,6 @@ namespace osu.Game.Screens.Play public int RestartCount; - public CursorContainer Cursor => RulesetContainer.Cursor; - public bool ProvidingUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded.Value; - private IAdjustableClock sourceClock; /// From acf518c20816b9ca61d1c9897c6aea94d957e4f1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Mar 2019 12:34:58 +0900 Subject: [PATCH 26/62] Move cursor inside playfield --- .../Edit/OsuEditRulesetContainer.cs | 7 +++++-- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 5 +++++ osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs | 4 ---- osu.Game/Rulesets/UI/Playfield.cs | 15 +++++++++++++++ osu.Game/Rulesets/UI/RulesetContainer.cs | 12 ++---------- osu.Game/Screens/Play/Player.cs | 4 ---- 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs index c293a5a4f8..8ee07f6467 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs @@ -16,8 +16,11 @@ namespace osu.Game.Rulesets.Osu.Edit { } - protected override CursorContainer CreateCursor() => null; + protected override Playfield CreatePlayfield() => new OsuPlayfieldNoCursor { Size = Vector2.One }; - protected override Playfield CreatePlayfield() => new OsuPlayfield { Size = Vector2.One }; + private class OsuPlayfieldNoCursor : OsuPlayfield + { + protected override CursorContainer CreateCursor() => null; + } } } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 2db2b45540..e2be955200 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -10,7 +10,9 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Connections; using osu.Game.Rulesets.UI; using System.Linq; +using osu.Framework.Graphics.Cursor; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Osu.UI.Cursor; namespace osu.Game.Rulesets.Osu.UI { @@ -34,6 +36,7 @@ namespace osu.Game.Rulesets.Osu.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { + Cursor, connectionLayer = new FollowPointRenderer { RelativeSizeAxes = Axes.Both, @@ -54,6 +57,8 @@ namespace osu.Game.Rulesets.Osu.UI }; } + protected override CursorContainer CreateCursor() => new GameplayCursorContainer(); + public override void Add(DrawableHitObject h) { h.OnNewResult += onNewResult; diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 805bbfb4d4..81482a9a01 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using osu.Framework.Graphics.Cursor; using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Input.Handlers; @@ -13,7 +12,6 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Osu.Scoring; -using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -59,7 +57,5 @@ namespace osu.Game.Rulesets.Osu.UI return first.StartTime - first.TimePreempt; } } - - protected override CursorContainer CreateCursor() => new GameplayCursorContainer(); } } diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 3b8a7353c6..c1cce52c8c 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; using osuTK; @@ -47,6 +48,8 @@ namespace osu.Game.Rulesets.UI /// public readonly BindableBool DisplayJudgements = new BindableBool(true); + public readonly BindableBool HasReplayLoaded = new BindableBool(); + /// /// Creates a new . /// @@ -55,6 +58,8 @@ namespace osu.Game.Rulesets.UI RelativeSizeAxes = Axes.Both; hitObjectContainerLazy = new Lazy(CreateHitObjectContainer); + + Cursor = CreateCursor(); } private WorkingBeatmap beatmap; @@ -82,6 +87,16 @@ namespace osu.Game.Rulesets.UI /// The DrawableHitObject to remove. public virtual bool Remove(DrawableHitObject h) => HitObjectContainer.Remove(h); + /// + /// Creates the cursor. May be null if no cursor is required. + /// + protected virtual CursorContainer CreateCursor() => null; + + /// + /// The cursor provided by this . May be null if no cursor is provided. + /// + public CursorContainer Cursor { get; } + /// /// Registers a as a nested . /// This does not add the to the draw hierarchy. diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index c9ad7bb5ec..ed5f23dc7f 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -76,12 +76,9 @@ namespace osu.Game.Rulesets.UI /// public Container Overlays { get; protected set; } - /// - /// The cursor provided by this . May be null if no cursor is provided. - /// - public CursorContainer Cursor { get; } + public CursorContainer Cursor => Playfield.Cursor; - public bool ProvidingUserCursor => Cursor != null && !HasReplayLoaded.Value; + public bool ProvidingUserCursor => Playfield.Cursor != null && !HasReplayLoaded.Value; protected override bool OnHover(HoverEvent e) => true; // required for IProvideCursor @@ -107,8 +104,6 @@ namespace osu.Game.Rulesets.UI KeyBindingInputManager.UseParentInput = !paused.NewValue; }; - - Cursor = CreateCursor(); } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) @@ -265,9 +260,6 @@ namespace osu.Game.Rulesets.UI Playfield }); - if (Cursor != null) - KeyBindingInputManager.Add(Cursor); - InternalChildren = new Drawable[] { KeyBindingInputManager, diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 0f4fa3e762..59349edcaa 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -193,10 +193,6 @@ namespace osu.Game.Screens.Play Origin = Anchor.Centre, Breaks = beatmap.Breaks }, - new ScalingContainer(ScalingMode.Gameplay) - { - Child = RulesetContainer.Cursor?.CreateProxy() ?? new Container(), - }, HUDOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, adjustableClock) { Anchor = Anchor.Centre, From 18826b3a5908056b76d7fad468a68fa3940b1148 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Mar 2019 17:12:57 +0900 Subject: [PATCH 27/62] Adjust cursor scale for its new surroundings --- osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs index ca8368155f..8c6723f5be 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor public OsuCursor() { Origin = Anchor.Centre; - Size = new Vector2(42); + Size = new Vector2(28); } protected override void SkinChanged(ISkinSource skin, bool allowFallback) From 7aa30ca3f67f36ad07dea543d3f9f21305b5df17 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Mar 2019 17:23:13 +0900 Subject: [PATCH 28/62] Change method of cursor creation --- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 5 +---- osu.Game/Rulesets/UI/Playfield.cs | 11 ++--------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index e2be955200..47a064beee 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -10,7 +10,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Connections; using osu.Game.Rulesets.UI; using System.Linq; -using osu.Framework.Graphics.Cursor; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.UI.Cursor; @@ -36,7 +35,6 @@ namespace osu.Game.Rulesets.Osu.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - Cursor, connectionLayer = new FollowPointRenderer { RelativeSizeAxes = Axes.Both, @@ -53,12 +51,11 @@ namespace osu.Game.Rulesets.Osu.UI RelativeSizeAxes = Axes.Both, Depth = -1, }, + Cursor = new GameplayCursorContainer(), } }; } - protected override CursorContainer CreateCursor() => new GameplayCursorContainer(); - public override void Add(DrawableHitObject h) { h.OnNewResult += onNewResult; diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index c1cce52c8c..708db55c4d 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -58,8 +58,6 @@ namespace osu.Game.Rulesets.UI RelativeSizeAxes = Axes.Both; hitObjectContainerLazy = new Lazy(CreateHitObjectContainer); - - Cursor = CreateCursor(); } private WorkingBeatmap beatmap; @@ -88,14 +86,9 @@ namespace osu.Game.Rulesets.UI public virtual bool Remove(DrawableHitObject h) => HitObjectContainer.Remove(h); /// - /// Creates the cursor. May be null if no cursor is required. + /// The cursor currently being used by this . May be null if no cursor is provided. /// - protected virtual CursorContainer CreateCursor() => null; - - /// - /// The cursor provided by this . May be null if no cursor is provided. - /// - public CursorContainer Cursor { get; } + public CursorContainer Cursor { get; protected set; } /// /// Registers a as a nested . From 62716851a1cc33875f68bb180c0630180b3ea608 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Mar 2019 17:36:25 +0900 Subject: [PATCH 29/62] Revert some unnecessary changes --- osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs | 6 ++++-- osu.Game/Rulesets/UI/Playfield.cs | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs index 8ee07f6467..7886a2393c 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Graphics.Cursor; using osu.Game.Beatmaps; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; @@ -20,7 +19,10 @@ namespace osu.Game.Rulesets.Osu.Edit private class OsuPlayfieldNoCursor : OsuPlayfield { - protected override CursorContainer CreateCursor() => null; + public OsuPlayfieldNoCursor() + { + Cursor?.Expire(); + } } } } diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 708db55c4d..f0c2b8859c 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -48,8 +48,6 @@ namespace osu.Game.Rulesets.UI /// public readonly BindableBool DisplayJudgements = new BindableBool(true); - public readonly BindableBool HasReplayLoaded = new BindableBool(); - /// /// Creates a new . /// From ffe53411f61a906338b25a92e49a95e80a75a467 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Mar 2019 17:44:58 +0900 Subject: [PATCH 30/62] Add back cursor proxying --- osu.Game/Screens/Play/Player.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 59349edcaa..715a414710 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -176,7 +176,7 @@ namespace osu.Game.Screens.Play OnRetry = restart, OnQuit = performUserRequestedExit, CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded.Value, - Children = new Container[] + Children = new[] { StoryboardContainer = CreateStoryboardContainer(), new ScalingContainer(ScalingMode.Gameplay) @@ -193,6 +193,8 @@ namespace osu.Game.Screens.Play Origin = Anchor.Centre, Breaks = beatmap.Breaks }, + // display the cursor above some HUD elements. + RulesetContainer.Cursor?.CreateProxy() ?? new Container(), HUDOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, adjustableClock) { Anchor = Anchor.Centre, From eb80549782d5fc0a8c49e6c0eab7f34d3e3451b9 Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Wed, 6 Mar 2019 18:18:47 +0900 Subject: [PATCH 31/62] Fix UpdateableBeatmapBackgroundSprite not disposing of previously loaded sprites --- .../UpdateableBeatmapBackgroundSprite.cs | 66 +++++++++++-------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 012926fb0e..773730c2fe 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Beatmaps.Drawables { /// - /// Display a baetmap background from a local source, but fallback to online source if not available. + /// Display a beatmap background from a local source, but fallback to online source if not available. /// public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable { @@ -26,37 +26,51 @@ namespace osu.Game.Beatmaps.Drawables this.beatmapSetCoverType = beatmapSetCoverType; } - protected override Drawable CreateDrawable(BeatmapInfo model) + private BeatmapInfo lastModel; + + protected override DelayedLoadWrapper CreateDelayedLoadWrapper(Drawable content, double timeBeforeLoad) { return new DelayedLoadUnloadWrapper(() => { - Drawable drawable; + // If DelayedLoadUnloadWrapper is attempting to RELOAD the same content (Beatmap), that means that it was + // previously UNLOADED and thus its children have been disposed of, so we need to recreate them here. + if (lastModel == Beatmap.Value) + return CreateDrawable(Beatmap.Value); - var localBeatmap = beatmaps.GetWorkingBeatmap(model); - - if (model?.BeatmapSet?.OnlineInfo != null) - drawable = new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); - else if (localBeatmap.BeatmapInfo.ID != 0) - { - // Fall back to local background if one exists - drawable = new BeatmapBackgroundSprite(localBeatmap); - } - else - { - // Use the default background if somehow an online set does not exist and we don't have a local copy. - drawable = new BeatmapBackgroundSprite(beatmaps.DefaultBeatmap); - } - - drawable.RelativeSizeAxes = Axes.Both; - drawable.Anchor = Anchor.Centre; - drawable.Origin = Anchor.Centre; - drawable.FillMode = FillMode.Fill; - drawable.OnLoadComplete = d => d.FadeInFromZero(400); - - return drawable; + // If the model has changed since the previous unload (or if there was no load), then we can safely use the given content + lastModel = Beatmap.Value; + return content; }, 500, 10000); } - protected override double FadeDuration => 0; + protected override Drawable CreateDrawable(BeatmapInfo model) + { + Drawable drawable; + + var localBeatmap = beatmaps.GetWorkingBeatmap(model); + + if (model?.BeatmapSet?.OnlineInfo != null) + { + drawable = new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); + } + else if (localBeatmap.BeatmapInfo.ID != 0) + { + // Fall back to local background if one exists + drawable = new BeatmapBackgroundSprite(localBeatmap); + } + else + { + // Use the default background if somehow an online set does not exist and we don't have a local copy. + drawable = new BeatmapBackgroundSprite(beatmaps.DefaultBeatmap); + } + + drawable.RelativeSizeAxes = Axes.Both; + drawable.Anchor = Anchor.Centre; + drawable.Origin = Anchor.Centre; + drawable.FillMode = FillMode.Fill; + drawable.OnLoadComplete = d => d.FadeInFromZero(400); + + return drawable; + } } } From 06b65e00c423adbe18d43fe3de050f6fde36067e Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Wed, 6 Mar 2019 18:53:53 +0900 Subject: [PATCH 32/62] Prevent null beatmap from creating an extra drawable --- .../Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 773730c2fe..4740b25ba9 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -34,7 +34,7 @@ namespace osu.Game.Beatmaps.Drawables { // If DelayedLoadUnloadWrapper is attempting to RELOAD the same content (Beatmap), that means that it was // previously UNLOADED and thus its children have been disposed of, so we need to recreate them here. - if (lastModel == Beatmap.Value) + if (lastModel == Beatmap.Value && Beatmap.Value != null) return CreateDrawable(Beatmap.Value); // If the model has changed since the previous unload (or if there was no load), then we can safely use the given content From ab0ac7a82a541ba790468b5852f9713edeca7e89 Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Wed, 6 Mar 2019 18:56:40 +0900 Subject: [PATCH 33/62] Pass through timeBeforeLoad instead of hardcoding --- .../Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 4740b25ba9..f0af09459f 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -40,7 +40,7 @@ namespace osu.Game.Beatmaps.Drawables // If the model has changed since the previous unload (or if there was no load), then we can safely use the given content lastModel = Beatmap.Value; return content; - }, 500, 10000); + }, timeBeforeLoad, 10000); } protected override Drawable CreateDrawable(BeatmapInfo model) From b5e89e2f3b05418ec84197ce59ae5c2934675cef Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Wed, 6 Mar 2019 18:55:01 +0900 Subject: [PATCH 34/62] Add additional testing to check for extra children in the future --- ...stCaseUpdateableBeatmapBackgroundSprite.cs | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs b/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs index 3ee617e092..9a2124450c 100644 --- a/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual { public class TestCaseUpdateableBeatmapBackgroundSprite : OsuTestCase { - private UpdateableBeatmapBackgroundSprite backgroundSprite; + private TestUpdateableBeatmapBackgroundSprite backgroundSprite; [Resolved] private BeatmapManager beatmaps { get; set; } @@ -28,30 +28,39 @@ namespace osu.Game.Tests.Visual var imported = ImportBeatmapTest.LoadOszIntoOsu(osu); - Child = backgroundSprite = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both }; + Child = backgroundSprite = new TestUpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both }; backgroundSprite.Beatmap.BindTo(beatmapBindable); var req = new GetBeatmapSetRequest(1); api.Queue(req); - AddStep("null", () => beatmapBindable.Value = null); - - AddStep("imported", () => beatmapBindable.Value = imported.Beatmaps.First()); + AddStep("load null beatmap", () => beatmapBindable.Value = null); + AddWaitStep(20, "wait for transition..."); + AddAssert("ensure only 1 child is present", () => backgroundSprite.ChildCount == 1); + AddStep("load imported beatmap", () => beatmapBindable.Value = imported.Beatmaps.First()); + AddWaitStep(20, "wait for transition..."); + AddAssert("ensure only 1 child is present", () => backgroundSprite.ChildCount == 1); if (api.IsLoggedIn) { AddUntilStep(() => req.Result != null, "wait for api response"); - - AddStep("online", () => beatmapBindable.Value = new BeatmapInfo + AddStep("load online beatmap", () => beatmapBindable.Value = new BeatmapInfo { BeatmapSet = req.Result?.ToBeatmapSet(rulesets) }); + AddWaitStep(20, "wait for transition..."); + AddAssert("ensure only 1 child is present", () => backgroundSprite.ChildCount == 1); } else { AddStep("online (login first)", () => { }); } } + + private class TestUpdateableBeatmapBackgroundSprite : UpdateableBeatmapBackgroundSprite + { + public int ChildCount => InternalChildren.Count; + } } } From 8a69fc5534b7dbe07f93987251ceb1b8378a0b5b Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Wed, 6 Mar 2019 19:57:09 +0900 Subject: [PATCH 35/62] Use AddUntilStep instead of AddWaitStep --- .../Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs b/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs index 9a2124450c..506121efd7 100644 --- a/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs @@ -36,11 +36,9 @@ namespace osu.Game.Tests.Visual api.Queue(req); AddStep("load null beatmap", () => beatmapBindable.Value = null); - AddWaitStep(20, "wait for transition..."); - AddAssert("ensure only 1 child is present", () => backgroundSprite.ChildCount == 1); + AddUntilStep(() => backgroundSprite.ChildCount == 1, "wait for cleanup..."); AddStep("load imported beatmap", () => beatmapBindable.Value = imported.Beatmaps.First()); - AddWaitStep(20, "wait for transition..."); - AddAssert("ensure only 1 child is present", () => backgroundSprite.ChildCount == 1); + AddUntilStep(() => backgroundSprite.ChildCount == 1, "wait for cleanup..."); if (api.IsLoggedIn) { @@ -49,8 +47,7 @@ namespace osu.Game.Tests.Visual { BeatmapSet = req.Result?.ToBeatmapSet(rulesets) }); - AddWaitStep(20, "wait for transition..."); - AddAssert("ensure only 1 child is present", () => backgroundSprite.ChildCount == 1); + AddUntilStep(() => backgroundSprite.ChildCount == 1, "wait for cleanup..."); } else { From 5de6e29294d07dac6823673d6e9c6d3146f913c4 Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Wed, 6 Mar 2019 17:13:41 +0900 Subject: [PATCH 36/62] Reset currentRoom state when cancelling room creation --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index a71106872e..902a8c1c57 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -53,6 +53,9 @@ namespace osu.Game.Screens.Multi.Match private MatchLeaderboard leaderboard; + [Resolved] + private Bindable currentRoom { get; set; } + public MatchSubScreen(Room room) { Title = room.RoomID.Value == null ? "New room" : room.Name.Value; @@ -182,6 +185,10 @@ namespace osu.Game.Screens.Multi.Match public override bool OnExiting(IScreen next) { RoomManager?.PartRoom(); + + if (roomId.Value == null) + currentRoom.Value = new Room(); + return base.OnExiting(next); } From 6e5ea78ca258e4a22e4ed36041959cc615126d5e Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Wed, 6 Mar 2019 17:13:28 +0900 Subject: [PATCH 37/62] Fix some nullref crashes when escaping out of new room creation --- osu.Game/Screens/Multi/Match/Components/Header.cs | 4 +++- osu.Game/Screens/Select/MatchSongSelect.cs | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 6a6a1f274c..e1592532a3 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -13,6 +14,7 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Play.HUD; using osuTK; @@ -108,7 +110,7 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - CurrentItem.BindValueChanged(item => modDisplay.Current.Value = item.NewValue?.RequiredMods, true); + CurrentItem.BindValueChanged(item => modDisplay.Current.Value = item.NewValue?.RequiredMods ?? Enumerable.Empty(), true); beatmapButton.Action = () => RequestBeatmapSelection?.Invoke(); } diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index f6d758df29..fcd07384e4 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Humanizer; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -61,7 +62,7 @@ namespace osu.Game.Screens.Select return true; Beatmap.Value = beatmaps.GetWorkingBeatmap(CurrentItem.Value?.Beatmap); - Beatmap.Value.Mods.Value = selectedMods.Value = CurrentItem.Value?.RequiredMods; + Beatmap.Value.Mods.Value = selectedMods.Value = CurrentItem.Value?.RequiredMods ?? Enumerable.Empty(); Ruleset.Value = CurrentItem.Value?.Ruleset; Beatmap.Disabled = true; From d97c070ef14c005394a10b24dd979b1fe2a29ec3 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 7 Mar 2019 13:45:55 +0900 Subject: [PATCH 38/62] Account for path width correctly in LineGraph --- osu.Game/Graphics/UserInterface/LineGraph.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs index 7a20dd3d16..b64c1f28dc 100644 --- a/osu.Game/Graphics/UserInterface/LineGraph.cs +++ b/osu.Game/Graphics/UserInterface/LineGraph.cs @@ -102,9 +102,9 @@ namespace osu.Game.Graphics.UserInterface for (int i = 0; i < values.Length; i++) { - float x = (i + count - values.Length) / (float)(count - 1) * DrawWidth - 1; - float y = GetYPosition(values[i]) * DrawHeight - 1; - // the -1 is for inner offset in path (actually -PathWidth) + // Make sure that we are accounting for path width when calculating vertex positions + float x = (i + count - values.Length) / (float)(count - 1) * (DrawWidth - path.PathWidth); + float y = GetYPosition(values[i]) * (DrawHeight - path.PathWidth); path.AddVertex(new Vector2(x, y)); } } From e13516c2bace6447459569353f5ee11076e70395 Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Thu, 7 Mar 2019 14:09:28 +0900 Subject: [PATCH 39/62] Only attempt to restore CurrentItem state if present --- osu.Game/Screens/Select/MatchSongSelect.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index f6d758df29..3dc152eebe 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -60,9 +60,12 @@ namespace osu.Game.Screens.Select if (base.OnExiting(next)) return true; - Beatmap.Value = beatmaps.GetWorkingBeatmap(CurrentItem.Value?.Beatmap); - Beatmap.Value.Mods.Value = selectedMods.Value = CurrentItem.Value?.RequiredMods; - Ruleset.Value = CurrentItem.Value?.Ruleset; + if (CurrentItem.Value != null) + { + Ruleset.Value = CurrentItem.Value.Ruleset; + Beatmap.Value = beatmaps.GetWorkingBeatmap(CurrentItem.Value.Beatmap); + Beatmap.Value.Mods.Value = selectedMods.Value = CurrentItem.Value.RequiredMods; + } Beatmap.Disabled = true; Ruleset.Disabled = true; From ee076bbbe3404e6fcaca370f9d3267c5d00db488 Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Thu, 7 Mar 2019 15:35:57 +0900 Subject: [PATCH 40/62] Fix chat channel ids not being updated on room creation --- osu.Game/Online/Multiplayer/Room.cs | 1 + .../Screens/Multi/Match/Components/MatchChatDisplay.cs | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 77236ce3c8..53089897f7 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -124,6 +124,7 @@ namespace osu.Game.Online.Multiplayer if (other.Host.Value != null && Host.Value?.Id != other.Host.Value.Id) Host.Value = other.Host.Value; + ChannelId.Value = other.ChannelId.Value; Status.Value = other.Status.Value; Availability.Value = other.Availability.Value; Type.Value = other.Type.Value; diff --git a/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs b/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs index bd8e4c7335..f8b64a54ef 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs @@ -28,13 +28,15 @@ namespace osu.Game.Screens.Multi.Match.Components { base.LoadComplete(); - roomId.BindValueChanged(_ => updateChannel(), true); + channelId.BindValueChanged(_ => updateChannel(), true); } private void updateChannel() { - if (roomId.Value != null) - Channel.Value = channelManager?.JoinChannel(new Channel { Id = channelId.Value, Type = ChannelType.Multiplayer, Name = $"#mp_{roomId.Value}" }); + if (roomId.Value == null || channelId.Value == 0) + return; + + Channel.Value = channelManager?.JoinChannel(new Channel { Id = channelId.Value, Type = ChannelType.Multiplayer, Name = $"#lazermp_{roomId.Value}" }); } } } From 58ef397f4ffaa3d5a73b544eb7fa80409a02a3e5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Mar 2019 20:30:14 +0900 Subject: [PATCH 41/62] Move all clock related gameplay logic inside GameplayClockContainer --- .../Screens/Play/GameplayClockContainer.cs | 151 +++++++++++ .../Screens/Play/HUD/PlayerSettingsOverlay.cs | 2 + osu.Game/Screens/Play/HUDOverlay.cs | 10 +- .../Screens/Play/PausableGameplayContainer.cs | 65 ++--- osu.Game/Screens/Play/Player.cs | 246 ++++++++---------- .../Play/PlayerSettings/PlaybackSettings.cs | 29 +-- 6 files changed, 292 insertions(+), 211 deletions(-) create mode 100644 osu.Game/Screens/Play/GameplayClockContainer.cs diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs new file mode 100644 index 0000000000..f769bfd326 --- /dev/null +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -0,0 +1,151 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using System.Threading.Tasks; +using osu.Framework; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Timing; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Screens.Play +{ + /// + /// Manages the various intricacies of the gameplay clock. + /// + public class GameplayClockContainer : Container + { + private readonly WorkingBeatmap beatmap; + + /// + /// The original source (usually a 's track). + /// + private readonly IAdjustableClock sourceClock; + + public readonly BindableBool IsPaused = new BindableBool(); + + /// + /// The decoupled clock used for gameplay. Should be used for seeks and clock control. + /// + private readonly DecoupleableInterpolatingFramedClock adjustableClock; + + /// + /// The final clock which is exposed to underlying components. + /// + [Cached] + private readonly GameplayClock gameplayClock; + + public readonly Bindable UserPlaybackRate = new BindableDouble(1) + { + Default = 1, + MinValue = 0.5, + MaxValue = 2, + Precision = 0.1, + }; + + private Bindable userAudioOffset; + + private readonly FramedOffsetClock offsetClock; + + public GameplayClockContainer(WorkingBeatmap beatmap, bool allowLeadIn, double gameplayStartTime) + { + RelativeSizeAxes = Axes.Both; + + this.beatmap = beatmap; + + sourceClock = (IAdjustableClock)beatmap.Track ?? new StopwatchClock(); + + adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; + + adjustableClock.Seek(allowLeadIn + ? Math.Min(0, gameplayStartTime - beatmap.BeatmapInfo.AudioLeadIn) + : gameplayStartTime); + + adjustableClock.ProcessFrame(); + + // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited. + // This only seems to be required on windows. We need to eventually figure out why, with a bit of luck. + var platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; + + // the final usable gameplay clock with user-set offsets applied. + offsetClock = new FramedOffsetClock(platformOffsetClock); + + // the clock to be exposed via DI to children. + gameplayClock = new GameplayClock(offsetClock); + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); + userAudioOffset.BindValueChanged(offset => offsetClock.Offset = offset.NewValue, true); + + UserPlaybackRate.ValueChanged += _ => updateRate(); + } + + public void Restart() + { + Task.Run(() => + { + sourceClock.Reset(); + + Schedule(() => + { + adjustableClock.ChangeSource(sourceClock); + updateRate(); + + this.Delay(750).Schedule(() => + { + if (!IsPaused.Value) + { + adjustableClock.Start(); + } + }); + }); + }); + } + + public void Start() + { + // Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time + // This accounts for the audio clock source potentially taking time to enter a completely stopped state + adjustableClock.Seek(adjustableClock.CurrentTime); + adjustableClock.Start(); + } + + public void Seek(double time) => adjustableClock.Seek(time); + + public void Stop() => adjustableClock.Stop(); + + public void ResetLocalAdjustments() + { + // In the case of replays, we may have changed the playback rate. + UserPlaybackRate.Value = 1; + } + + protected override void Update() + { + if (!IsPaused.Value) + offsetClock.ProcessFrame(); + + base.Update(); + } + + private void updateRate() + { + if (sourceClock == null) return; + + sourceClock.Rate = 1; + foreach (var mod in beatmap.Mods.Value.OfType()) + mod.ApplyToClock(sourceClock); + + sourceClock.Rate *= UserPlaybackRate.Value; + } + } +} diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index d3dba88281..e99f6d836e 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -19,7 +19,9 @@ namespace osu.Game.Screens.Play.HUD public readonly PlaybackSettings PlaybackSettings; public readonly VisualSettings VisualSettings; + //public readonly CollectionSettings CollectionSettings; + //public readonly DiscussionSettings DiscussionSettings; public PlayerSettingsOverlay() diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index a19b0d1e5c..4fd0572c1a 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -1,12 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; @@ -40,7 +40,9 @@ namespace osu.Game.Screens.Play private static bool hasShownNotificationOnce; - public HUDOverlay(ScoreProcessor scoreProcessor, RulesetContainer rulesetContainer, WorkingBeatmap working, IAdjustableClock adjustableClock) + public Action RequestSeek; + + public HUDOverlay(ScoreProcessor scoreProcessor, RulesetContainer rulesetContainer, WorkingBeatmap working) { RelativeSizeAxes = Axes.Both; @@ -92,11 +94,9 @@ namespace osu.Game.Screens.Play Progress.Objects = rulesetContainer.Objects; Progress.AllowSeeking = rulesetContainer.HasReplayLoaded.Value; - Progress.RequestSeek = pos => adjustableClock.Seek(pos); + Progress.RequestSeek = time => RequestSeek(time); ModDisplay.Current.BindTo(working.Mods); - - PlayerSettingsOverlay.PlaybackSettings.AdjustableClock = adjustableClock; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Screens/Play/PausableGameplayContainer.cs b/osu.Game/Screens/Play/PausableGameplayContainer.cs index fa475deb34..99f0083b55 100644 --- a/osu.Game/Screens/Play/PausableGameplayContainer.cs +++ b/osu.Game/Screens/Play/PausableGameplayContainer.cs @@ -7,16 +7,13 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Timing; using osu.Game.Graphics; using osuTK.Graphics; namespace osu.Game.Screens.Play { /// - /// A container which handles pausing children, displaying a pause overlay with choices and processing the clock. - /// Exposes a to children via DI. - /// This alleviates a lot of the intricate pause logic from being in + /// A container which handles pausing children, displaying an overlay blocking its children during paused state. /// public class PausableGameplayContainer : Container { @@ -44,46 +41,33 @@ namespace osu.Game.Screens.Play public Action OnRetry; public Action OnQuit; - private readonly FramedClock offsetClock; - private readonly DecoupleableInterpolatingFramedClock adjustableClock; - - /// - /// The final clock which is exposed to underlying components. - /// - [Cached] - private readonly GameplayClock gameplayClock; + public Action Stop; + public Action Start; /// /// Creates a new . /// - /// The gameplay clock. This is the clock that will process frames. Includes user/system offsets. - /// The seekable clock. This is the clock that will be paused and resumed. Should not be processed (it is processed automatically by ). - public PausableGameplayContainer(FramedClock offsetClock, DecoupleableInterpolatingFramedClock adjustableClock) + public PausableGameplayContainer() { - this.offsetClock = offsetClock; - this.adjustableClock = adjustableClock; - - gameplayClock = new GameplayClock(offsetClock); - RelativeSizeAxes = Axes.Both; - AddInternal(content = new Container + InternalChildren = new[] { - Clock = this.offsetClock, - ProcessCustomClock = false, - RelativeSizeAxes = Axes.Both - }); - - AddInternal(pauseOverlay = new PauseOverlay - { - OnResume = () => + content = new Container { - IsResuming = true; - this.Delay(400).Schedule(Resume); + RelativeSizeAxes = Axes.Both }, - OnRetry = () => OnRetry(), - OnQuit = () => OnQuit(), - }); + pauseOverlay = new PauseOverlay + { + OnResume = () => + { + IsResuming = true; + this.Delay(400).Schedule(Resume); + }, + OnRetry = () => OnRetry(), + OnQuit = () => OnQuit(), + } + }; } public void Pause(bool force = false) => Schedule(() => // Scheduled to ensure a stable position in execution order, no matter how it was called. @@ -93,7 +77,7 @@ namespace osu.Game.Screens.Play if (IsPaused.Value) return; // stop the seekable clock (stops the audio eventually) - adjustableClock.Stop(); + Stop?.Invoke(); IsPaused.Value = true; pauseOverlay.Show(); @@ -105,14 +89,12 @@ namespace osu.Game.Screens.Play { if (!IsPaused.Value) return; - IsPaused.Value = false; IsResuming = false; lastPauseActionTime = Time.Current; - // Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time - // This accounts for the audio clock source potentially taking time to enter a completely stopped state - adjustableClock.Seek(adjustableClock.CurrentTime); - adjustableClock.Start(); + IsPaused.Value = false; + + Start?.Invoke(); pauseOverlay.Hide(); } @@ -131,9 +113,6 @@ namespace osu.Game.Screens.Play if (!game.IsActive.Value && CanPause) Pause(); - if (!IsPaused.Value) - offsetClock.ProcessFrame(); - base.Update(); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 44707c74f5..429b9dda91 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -3,8 +3,6 @@ using System; using System.Linq; -using System.Threading.Tasks; -using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -16,7 +14,6 @@ using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Framework.Screens; using osu.Framework.Threading; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.Containers; @@ -53,7 +50,6 @@ namespace osu.Game.Screens.Play public bool AllowResults { get; set; } = true; private Bindable mouseWheelDisabled; - private Bindable userAudioOffset; private readonly Bindable storyboardReplacesBackground = new Bindable(); @@ -62,13 +58,6 @@ namespace osu.Game.Screens.Play public CursorContainer Cursor => RulesetContainer.Cursor; public bool ProvidingUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded.Value; - private IAdjustableClock sourceClock; - - /// - /// The decoupled clock used for gameplay. Should be used for seeks and clock control. - /// - private DecoupleableInterpolatingFramedClock adjustableClock; - [Resolved] private ScoreManager scoreManager { get; set; } @@ -98,25 +87,117 @@ namespace osu.Game.Screens.Play public bool LoadedBeatmapSuccessfully => RulesetContainer?.Objects.Any() == true; + private GameplayClockContainer gameplayClockContainer; + [BackgroundDependencyLoader] private void load(AudioManager audio, APIAccess api, OsuConfigManager config) { this.api = api; - WorkingBeatmap working = Beatmap.Value; - if (working is DummyWorkingBeatmap) + WorkingBeatmap working = loadBeatmap(); + + if (working == null) return; sampleRestart = audio.Sample.Get(@"Gameplay/restart"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); - userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); - IBeatmap beatmap; + ScoreProcessor = RulesetContainer.CreateScoreProcessor(); + if (!ScoreProcessor.Mode.Disabled) + config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); + + InternalChild = gameplayClockContainer = new GameplayClockContainer(working, AllowLeadIn, RulesetContainer.GameplayStartTime); + + gameplayClockContainer.Children = new Drawable[] + { + PausableGameplayContainer = new PausableGameplayContainer + { + Retries = RestartCount, + OnRetry = restart, + OnQuit = performUserRequestedExit, + Start = gameplayClockContainer.Start, + Stop = gameplayClockContainer.Stop, + + CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded.Value, + Children = new Container[] + { + StoryboardContainer = CreateStoryboardContainer(), + new ScalingContainer(ScalingMode.Gameplay) + { + Child = new LocalSkinOverrideContainer(working.Skin) + { + RelativeSizeAxes = Axes.Both, + Child = RulesetContainer + } + }, + new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Breaks = working.Beatmap.Breaks + }, + new ScalingContainer(ScalingMode.Gameplay) + { + Child = RulesetContainer.Cursor?.CreateProxy() ?? new Container(), + }, + HUDOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working) + { + RequestSeek = gameplayClockContainer.Seek, + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }, + new SkipOverlay(RulesetContainer.GameplayStartTime) + { + RequestSeek = gameplayClockContainer.Seek + }, + } + }, + failOverlay = new FailOverlay + { + OnRetry = restart, + OnQuit = performUserRequestedExit, + }, + new HotkeyRetryOverlay + { + Action = () => + { + if (!this.IsCurrentScreen()) return; + + fadeOut(true); + restart(); + }, + } + }; + + // bind clock into components that require it + PausableGameplayContainer.IsPaused.BindTo(gameplayClockContainer.IsPaused); + RulesetContainer.IsPaused.BindTo(gameplayClockContainer.IsPaused); + HUDOverlay.PlayerSettingsOverlay.PlaybackSettings.UserPlaybackRate.BindTo(gameplayClockContainer.UserPlaybackRate); + + HUDOverlay.HoldToQuit.Action = performUserRequestedExit; + HUDOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded); + + if (ShowStoryboard.Value) + initializeStoryboard(false); + + // Bind ScoreProcessor to ourselves + ScoreProcessor.AllJudged += onCompletion; + ScoreProcessor.Failed += onFail; + + foreach (var mod in Beatmap.Value.Mods.Value.OfType()) + mod.ApplyToScoreProcessor(ScoreProcessor); + } + + private WorkingBeatmap loadBeatmap() + { + WorkingBeatmap working = Beatmap.Value; + if (working is DummyWorkingBeatmap) + return null; try { - beatmap = working.Beatmap; + var beatmap = working.Beatmap; if (beatmap == null) throw new InvalidOperationException("Beatmap was not loaded"); @@ -140,119 +221,17 @@ namespace osu.Game.Screens.Play if (!RulesetContainer.Objects.Any()) { Logger.Log("Beatmap contains no hit objects!", level: LogLevel.Error); - return; + return null; } } catch (Exception e) { Logger.Error(e, "Could not load beatmap sucessfully!"); //couldn't load, hard abort! - return; + return null; } - sourceClock = (IAdjustableClock)working.Track ?? new StopwatchClock(); - adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; - - adjustableClock.Seek(AllowLeadIn - ? Math.Min(0, RulesetContainer.GameplayStartTime - beatmap.BeatmapInfo.AudioLeadIn) - : RulesetContainer.GameplayStartTime); - - adjustableClock.ProcessFrame(); - - // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited. - // This only seems to be required on windows. We need to eventually figure out why, with a bit of luck. - var platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; - - // the final usable gameplay clock with user-set offsets applied. - var offsetClock = new FramedOffsetClock(platformOffsetClock); - - userAudioOffset.ValueChanged += offset => offsetClock.Offset = offset.NewValue; - userAudioOffset.TriggerChange(); - - ScoreProcessor = RulesetContainer.CreateScoreProcessor(); - if (!ScoreProcessor.Mode.Disabled) - config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - - InternalChildren = new Drawable[] - { - PausableGameplayContainer = new PausableGameplayContainer(offsetClock, adjustableClock) - { - Retries = RestartCount, - OnRetry = restart, - OnQuit = performUserRequestedExit, - CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded.Value, - Children = new Container[] - { - StoryboardContainer = CreateStoryboardContainer(), - new ScalingContainer(ScalingMode.Gameplay) - { - Child = new LocalSkinOverrideContainer(working.Skin) - { - RelativeSizeAxes = Axes.Both, - Child = RulesetContainer - } - }, - new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Breaks = beatmap.Breaks - }, - new ScalingContainer(ScalingMode.Gameplay) - { - Child = RulesetContainer.Cursor?.CreateProxy() ?? new Container(), - }, - HUDOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, adjustableClock) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre - }, - new SkipOverlay(RulesetContainer.GameplayStartTime) - { - RequestSeek = time => adjustableClock.Seek(time) - }, - } - }, - failOverlay = new FailOverlay - { - OnRetry = restart, - OnQuit = performUserRequestedExit, - }, - new HotkeyRetryOverlay - { - Action = () => - { - if (!this.IsCurrentScreen()) return; - - fadeOut(true); - restart(); - }, - } - }; - - HUDOverlay.HoldToQuit.Action = performUserRequestedExit; - HUDOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded); - - RulesetContainer.IsPaused.BindTo(PausableGameplayContainer.IsPaused); - - if (ShowStoryboard.Value) - initializeStoryboard(false); - - // Bind ScoreProcessor to ourselves - ScoreProcessor.AllJudged += onCompletion; - ScoreProcessor.Failed += onFail; - - foreach (var mod in Beatmap.Value.Mods.Value.OfType()) - mod.ApplyToScoreProcessor(ScoreProcessor); - } - - private void applyRateFromMods() - { - if (sourceClock == null) return; - - sourceClock.Rate = 1; - foreach (var mod in Beatmap.Value.Mods.Value.OfType()) - mod.ApplyToClock(sourceClock); + return working; } private void performUserRequestedExit() @@ -321,7 +300,7 @@ namespace osu.Game.Screens.Play if (Beatmap.Value.Mods.Value.OfType().Any(m => !m.AllowFail)) return false; - adjustableClock.Stop(); + gameplayClockContainer.Stop(); HasFailed = true; failOverlay.Retries = RestartCount; @@ -355,24 +334,7 @@ namespace osu.Game.Screens.Play storyboardReplacesBackground.Value = Beatmap.Value.Storyboard.ReplacesBackground && Beatmap.Value.Storyboard.HasDrawable; - Task.Run(() => - { - sourceClock.Reset(); - - Schedule(() => - { - adjustableClock.ChangeSource(sourceClock); - applyRateFromMods(); - - this.Delay(750).Schedule(() => - { - if (!PausableGameplayContainer.IsPaused.Value) - { - adjustableClock.Start(); - } - }); - }); - }); + gameplayClockContainer.Restart(); PausableGameplayContainer.Alpha = 0; PausableGameplayContainer.FadeIn(750, Easing.OutQuint); @@ -395,8 +357,8 @@ namespace osu.Game.Screens.Play if ((!AllowPause || HasFailed || !ValidForResume || PausableGameplayContainer?.IsPaused.Value != false || RulesetContainer?.HasReplayLoaded.Value != false) && (!PausableGameplayContainer?.IsResuming ?? true)) { - // In the case of replays, we may have changed the playback rate. - applyRateFromMods(); + gameplayClockContainer.ResetLocalAdjustments(); + fadeOut(); return base.OnExiting(next); } diff --git a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs index ebbed299f7..c691d161ed 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs @@ -4,7 +4,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Timing; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -16,7 +15,13 @@ namespace osu.Game.Screens.Play.PlayerSettings protected override string Title => @"playback"; - public IAdjustableClock AdjustableClock { set; get; } + public readonly Bindable UserPlaybackRate = new BindableDouble(1) + { + Default = 1, + MinValue = 0.5, + MaxValue = 2, + Precision = 0.1, + }; private readonly PlayerSliderBar rateSlider; @@ -47,31 +52,13 @@ namespace osu.Game.Screens.Play.PlayerSettings } }, }, - rateSlider = new PlayerSliderBar - { - Bindable = new BindableDouble(1) - { - Default = 1, - MinValue = 0.5, - MaxValue = 2, - Precision = 0.1, - }, - } + rateSlider = new PlayerSliderBar { Bindable = UserPlaybackRate } }; } protected override void LoadComplete() { base.LoadComplete(); - - if (AdjustableClock == null) - return; - - var clockRate = AdjustableClock.Rate; - - // can't trigger this line instantly as the underlying clock may not be ready to accept adjustments yet. - rateSlider.Bindable.ValueChanged += multiplier => AdjustableClock.Rate = clockRate * multiplier.NewValue; - rateSlider.Bindable.BindValueChanged(multiplier => multiplierText.Text = $"{multiplier.NewValue:0.0}x", true); } } From 57204b4361b86a232efa8d0f1fdfbffe5fb79094 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Mar 2019 12:14:18 +0900 Subject: [PATCH 42/62] Add JIT as abbreviation --- osu.sln.DotSettings | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 3c6a6dd2a9..b1ac31f2ce 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -262,6 +262,7 @@ IL IP IPC + JIT LTRB MD5 NS From 64b6eaa84474b526fae71a09f7bc4c53d53e6948 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Mar 2019 12:16:17 +0900 Subject: [PATCH 43/62] Simplify inward bindings --- osu.Game/Screens/Play/Player.cs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 429b9dda91..50ecf5443a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -118,9 +118,10 @@ namespace osu.Game.Screens.Play OnQuit = performUserRequestedExit, Start = gameplayClockContainer.Start, Stop = gameplayClockContainer.Stop, + IsPaused = { BindTarget = gameplayClockContainer.IsPaused }, CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded.Value, - Children = new Container[] + Children = new[] { StoryboardContainer = CreateStoryboardContainer(), new ScalingContainer(ScalingMode.Gameplay) @@ -137,12 +138,12 @@ namespace osu.Game.Screens.Play Origin = Anchor.Centre, Breaks = working.Beatmap.Breaks }, - new ScalingContainer(ScalingMode.Gameplay) - { - Child = RulesetContainer.Cursor?.CreateProxy() ?? new Container(), - }, + RulesetContainer.Cursor?.CreateProxy() ?? new Container(), HUDOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working) { + HoldToQuit = { Action = performUserRequestedExit }, + PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = gameplayClockContainer.UserPlaybackRate } } }, + KeyCounter = { Visible = { BindTarget = RulesetContainer.HasReplayLoaded } }, RequestSeek = gameplayClockContainer.Seek, Anchor = Anchor.Centre, Origin = Anchor.Centre @@ -171,12 +172,7 @@ namespace osu.Game.Screens.Play }; // bind clock into components that require it - PausableGameplayContainer.IsPaused.BindTo(gameplayClockContainer.IsPaused); RulesetContainer.IsPaused.BindTo(gameplayClockContainer.IsPaused); - HUDOverlay.PlayerSettingsOverlay.PlaybackSettings.UserPlaybackRate.BindTo(gameplayClockContainer.UserPlaybackRate); - - HUDOverlay.HoldToQuit.Action = performUserRequestedExit; - HUDOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded); if (ShowStoryboard.Value) initializeStoryboard(false); From 50c1b3a576c0e1a86edd4b86cd1d6b6c47b561a5 Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Thu, 7 Mar 2019 16:49:48 +0900 Subject: [PATCH 44/62] Move room resetting logic from MatchSubScreen to LoungeSubScreen --- osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs | 8 ++++++++ osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index dd1e060125..7cbae611ea 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -107,6 +107,14 @@ namespace osu.Game.Screens.Multi.Lounge Filter.Search.HoldFocus = false; } + public override void OnResuming(IScreen last) + { + base.OnResuming(last); + + if (currentRoom.Value?.RoomID.Value == null) + currentRoom.Value = new Room(); + } + private void joinRequested(Room room) { processingOverlay.Show(); diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 902a8c1c57..a71106872e 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -53,9 +53,6 @@ namespace osu.Game.Screens.Multi.Match private MatchLeaderboard leaderboard; - [Resolved] - private Bindable currentRoom { get; set; } - public MatchSubScreen(Room room) { Title = room.RoomID.Value == null ? "New room" : room.Name.Value; @@ -185,10 +182,6 @@ namespace osu.Game.Screens.Multi.Match public override bool OnExiting(IScreen next) { RoomManager?.PartRoom(); - - if (roomId.Value == null) - currentRoom.Value = new Room(); - return base.OnExiting(next); } From b2f4850275978a1a1867b4e0b54a0326ec6154c7 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 7 Mar 2019 17:25:51 +0900 Subject: [PATCH 45/62] Apply twice the line radius in order to properly account for diameter --- osu.Game/Graphics/UserInterface/LineGraph.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs index b64c1f28dc..27cdccd556 100644 --- a/osu.Game/Graphics/UserInterface/LineGraph.cs +++ b/osu.Game/Graphics/UserInterface/LineGraph.cs @@ -103,8 +103,9 @@ namespace osu.Game.Graphics.UserInterface for (int i = 0; i < values.Length; i++) { // Make sure that we are accounting for path width when calculating vertex positions - float x = (i + count - values.Length) / (float)(count - 1) * (DrawWidth - path.PathWidth); - float y = GetYPosition(values[i]) * (DrawHeight - path.PathWidth); + // We need to apply 2x the path radius to account for it because the full diameter of the line accounts into height + float x = (i + count - values.Length) / (float)(count - 1) * (DrawWidth - 2 * path.PathWidth); + float y = GetYPosition(values[i]) * (DrawHeight - 2 * path.PathWidth); path.AddVertex(new Vector2(x, y)); } } From b3e046c4d1d5ac26e892768027024a403e5e70fe Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 7 Mar 2019 17:39:19 +0900 Subject: [PATCH 46/62] Rename PathWidth to PathRadius --- .../Blueprints/Sliders/Components/PathControlPointPiece.cs | 2 +- .../Objects/Drawables/Pieces/SliderBody.cs | 4 ++-- osu.Game/Graphics/UserInterface/LineGraph.cs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index a164b7e6bb..e257369ad9 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components path = new SmoothPath { Anchor = Anchor.Centre, - PathWidth = 1 + PathRadius = 1 }, marker = new CircularContainer { diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs index b088f1914b..6f94f5945a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs @@ -21,8 +21,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces public float PathWidth { - get => path.PathWidth; - set => path.PathWidth = value; + get => path.PathRadius; + set => path.PathRadius = value; } /// diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs index 27cdccd556..74025b71ff 100644 --- a/osu.Game/Graphics/UserInterface/LineGraph.cs +++ b/osu.Game/Graphics/UserInterface/LineGraph.cs @@ -69,7 +69,7 @@ namespace osu.Game.Graphics.UserInterface { Masking = true, RelativeSizeAxes = Axes.Both, - Child = path = new SmoothPath { RelativeSizeAxes = Axes.Both, PathWidth = 1 } + Child = path = new SmoothPath { RelativeSizeAxes = Axes.Both, PathRadius = 1 } }); } @@ -104,8 +104,8 @@ namespace osu.Game.Graphics.UserInterface { // Make sure that we are accounting for path width when calculating vertex positions // We need to apply 2x the path radius to account for it because the full diameter of the line accounts into height - float x = (i + count - values.Length) / (float)(count - 1) * (DrawWidth - 2 * path.PathWidth); - float y = GetYPosition(values[i]) * (DrawHeight - 2 * path.PathWidth); + float x = (i + count - values.Length) / (float)(count - 1) * (DrawWidth - 2 * path.PathRadius); + float y = GetYPosition(values[i]) * (DrawHeight - 2 * path.PathRadius); path.AddVertex(new Vector2(x, y)); } } From 04d756524db42dbad9a97c5bed10fc788d47aa3f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 7 Mar 2019 18:30:18 +0900 Subject: [PATCH 47/62] Adjust with shader changes --- osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs | 6 +++--- osu.Game/Graphics/Backgrounds/Triangles.cs | 6 +++--- osu.Game/Rulesets/Mods/ModFlashlight.cs | 4 ++-- osu.Game/Screens/Loader.cs | 4 ++-- osu.Game/Screens/Menu/LogoVisualisation.cs | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs index 57c46f4379..03dbf7ac63 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { private int currentIndex; - private Shader shader; + private IShader shader; private Texture texture; private Vector2 size => texture.Size * Scale; @@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor [BackgroundDependencyLoader] private void load(ShaderManager shaders, TextureStore textures) { - shader = shaders?.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE); + shader = shaders.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE); texture = textures.Get(@"Cursor/cursortrail"); Scale = new Vector2(1 / texture.ScaleAdjust); } @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private class TrailDrawNode : DrawNode { - public Shader Shader; + public IShader Shader; public Texture Texture; public float Time; diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 3582a3635f..c67d779c37 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -64,7 +64,7 @@ namespace osu.Game.Graphics.Backgrounds private readonly SortedList parts = new SortedList(Comparer.Default); - private Shader shader; + private IShader shader; private readonly Texture texture; public Triangles() @@ -75,7 +75,7 @@ namespace osu.Game.Graphics.Backgrounds [BackgroundDependencyLoader] private void load(ShaderManager shaders) { - shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); + shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); } protected override void LoadComplete() @@ -196,7 +196,7 @@ namespace osu.Game.Graphics.Backgrounds private class TrianglesDrawNode : DrawNode { - public Shader Shader; + public IShader Shader; public Texture Texture; public readonly List Parts = new List(); diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index dfada5614a..ab095f417a 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mods public abstract class Flashlight : Drawable { internal BindableInt Combo; - private Shader shader; + private IShader shader; protected override DrawNode CreateDrawNode() => new FlashlightDrawNode(); @@ -139,7 +139,7 @@ namespace osu.Game.Rulesets.Mods private class FlashlightDrawNode : DrawNode { - public Shader Shader; + public IShader Shader; public Quad ScreenSpaceDrawQuad; public Vector2 FlashlightPosition; public Vector2 FlashlightSize; diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index 0db0f1a1a3..d858cb076a 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -89,7 +89,7 @@ namespace osu.Game.Screens /// public class ShaderPrecompiler : Drawable { - private readonly List loadTargets = new List(); + private readonly List loadTargets = new List(); public bool FinishedCompiling { get; private set; } @@ -106,7 +106,7 @@ namespace osu.Game.Screens loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE)); } - protected virtual bool AllLoaded => loadTargets.All(s => s.Loaded); + protected virtual bool AllLoaded => loadTargets.All(s => s.IsLoaded); protected override void Update() { diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index fdf13091be..a41a12927b 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -63,7 +63,7 @@ namespace osu.Game.Screens.Menu private readonly float[] frequencyAmplitudes = new float[256]; - private Shader shader; + private IShader shader; private readonly Texture texture; public LogoVisualisation() @@ -146,7 +146,7 @@ namespace osu.Game.Screens.Menu private class VisualisationDrawNode : DrawNode { - public Shader Shader; + public IShader Shader; public Texture Texture; //Asuming the logo is a circle, we don't need a second dimension. From 1f44dde96b3d67d60daa82648621c983ce243a94 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Mar 2019 18:30:31 +0900 Subject: [PATCH 48/62] Fix autoplay tests not working --- .../Mods/CatchModAutoplay.cs | 2 +- .../Replays/CatchAutoGenerator.cs | 7 +++-- .../Mods/ManiaModAutoplay.cs | 2 +- .../Replays/ManiaAutoGenerator.cs | 3 +- osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs | 2 +- .../Replays/OsuAutoGenerator.cs | 5 +++- .../Replays/OsuAutoGeneratorBase.cs | 5 ++-- .../Mods/TaikoModAutoplay.cs | 2 +- .../Replays/TaikoAutoGenerator.cs | 7 +++-- osu.Game.Tests/Visual/TestCaseReplay.cs | 30 ++++++++++++++----- osu.Game/Rulesets/Mods/ModAutoplay.cs | 8 ++--- osu.Game/Rulesets/Replays/AutoGenerator.cs | 8 ++--- osu.Game/Rulesets/Ruleset.cs | 2 +- 13 files changed, 51 insertions(+), 32 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs b/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs index 612df5bde5..692e63fa69 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModAutoplay : ModAutoplay { - protected override Score CreateReplayScore(Beatmap beatmap) => new Score + public override Score CreateReplayScore(IBeatmap beatmap) => new Score { ScoreInfo = new ScoreInfo { User = new User { Username = "osu!salad!" } }, Replay = new CatchAutoGenerator(beatmap).Generate(), diff --git a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs index 2fd05483ef..daa3f61de3 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs @@ -6,17 +6,20 @@ using System.Linq; using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Replays; +using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Catch.Replays { - internal class CatchAutoGenerator : AutoGenerator + internal class CatchAutoGenerator : AutoGenerator { public const double RELEASE_DELAY = 20; - public CatchAutoGenerator(Beatmap beatmap) + public new CatchBeatmap Beatmap => (CatchBeatmap)base.Beatmap; + + public CatchAutoGenerator(IBeatmap beatmap) : base(beatmap) { Replay = new Replay(); diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs index 02eb7ac883..c05e979e9a 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Mania.Mods { public class ManiaModAutoplay : ModAutoplay { - protected override Score CreateReplayScore(Beatmap beatmap) => new Score + public override Score CreateReplayScore(IBeatmap beatmap) => new Score { ScoreInfo = new ScoreInfo { User = new User { Username = "osu!topus!" } }, Replay = new ManiaAutoGenerator((ManiaBeatmap)beatmap).Generate(), diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index df6afa040e..65b7d54cd2 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -5,13 +5,12 @@ using System.Collections.Generic; using System.Linq; using osu.Game.Replays; using osu.Game.Rulesets.Mania.Beatmaps; -using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Mania.Replays { - internal class ManiaAutoGenerator : AutoGenerator + internal class ManiaAutoGenerator : AutoGenerator { public const double RELEASE_DELAY = 20; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs index d7ba0d4da9..bea2bbcb32 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).Append(typeof(OsuModSpunOut)).ToArray(); - protected override Score CreateReplayScore(Beatmap beatmap) => new Score + public override Score CreateReplayScore(IBeatmap beatmap) => new Score { ScoreInfo = new ScoreInfo { User = new User { Username = "Autoplay" } }, Replay = new OsuAutoGenerator(beatmap).Generate() diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index b0fb85d7ed..c1aaa7767e 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -10,12 +10,15 @@ using System.Linq; using osu.Framework.Graphics; using osu.Game.Replays; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Replays { public class OsuAutoGenerator : OsuAutoGeneratorBase { + public new OsuBeatmap Beatmap => (OsuBeatmap)base.Beatmap; + #region Parameters /// @@ -42,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Replays #region Construction / Initialisation - public OsuAutoGenerator(Beatmap beatmap) + public OsuAutoGenerator(IBeatmap beatmap) : base(beatmap) { // Already superhuman, but still somewhat realistic diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs index 9a60f0cafc..9ab358ee12 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs @@ -3,7 +3,6 @@ using osuTK; using osu.Game.Beatmaps; -using osu.Game.Rulesets.Osu.Objects; using System; using System.Collections.Generic; using osu.Game.Replays; @@ -12,7 +11,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Osu.Replays { - public abstract class OsuAutoGeneratorBase : AutoGenerator + public abstract class OsuAutoGeneratorBase : AutoGenerator { #region Constants @@ -35,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Replays protected Replay Replay; protected List Frames => Replay.Frames; - protected OsuAutoGeneratorBase(Beatmap beatmap) + protected OsuAutoGeneratorBase(IBeatmap beatmap) : base(beatmap) { Replay = new Replay(); diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs index 4e5491da9c..5b890b3d03 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModAutoplay : ModAutoplay { - protected override Score CreateReplayScore(Beatmap beatmap) => new Score + public override Score CreateReplayScore(IBeatmap beatmap) => new Score { ScoreInfo = new ScoreInfo { User = new User { Username = "mekkadosu!" } }, Replay = new TaikoAutoGenerator(beatmap).Generate(), diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 14a6f98480..01ba53e07b 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -9,14 +9,17 @@ using osu.Game.Replays; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Replays; +using osu.Game.Rulesets.Taiko.Beatmaps; namespace osu.Game.Rulesets.Taiko.Replays { - public class TaikoAutoGenerator : AutoGenerator + public class TaikoAutoGenerator : AutoGenerator { + public new TaikoBeatmap Beatmap => (TaikoBeatmap)base.Beatmap; + private const double swell_hit_speed = 50; - public TaikoAutoGenerator(Beatmap beatmap) + public TaikoAutoGenerator(IBeatmap beatmap) : base(beatmap) { Replay = new Replay(); diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs index c12015a019..c34190d567 100644 --- a/osu.Game.Tests/Visual/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/TestCaseReplay.cs @@ -1,10 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.ComponentModel; using System.Linq; using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual @@ -14,15 +16,27 @@ namespace osu.Game.Tests.Visual { protected override Player CreatePlayer(Ruleset ruleset) { - // We create a dummy RulesetContainer just to get the replay - we don't want to use mods here - // to simulate setting a replay rather than having the replay already set for us - Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); - var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(Beatmap.Value); + var beatmap = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo); - // Reset the mods - Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay)); + return new ScoreAccessibleReplayPlayer(ruleset.GetAutoplayMod().CreateReplayScore(beatmap)); + } - return new ReplayPlayer(dummyRulesetContainer.ReplayScore); + protected override void AddCheckSteps(Func player) + { + base.AddCheckSteps(player); + AddUntilStep(() => ((ScoreAccessibleReplayPlayer)player()).ScoreProcessor.TotalScore.Value > 0, "score above zero"); + AddUntilStep(() => ((ScoreAccessibleReplayPlayer)player()).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys"); + } + + private class ScoreAccessibleReplayPlayer : ReplayPlayer + { + public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; + public new HUDOverlay HUDOverlay => base.HUDOverlay; + + public ScoreAccessibleReplayPlayer(Score score) + : base(score) + { + } } } } diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index 22e70b446e..44c78f8436 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -14,10 +14,6 @@ namespace osu.Game.Rulesets.Mods public abstract class ModAutoplay : ModAutoplay, IApplicableToRulesetContainer where T : HitObject { - protected virtual Score CreateReplayScore(Beatmap beatmap) => new Score { Replay = new Replay() }; - - public override bool HasImplementation => GetType().GenericTypeArguments.Length == 0; - public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) => rulesetContainer.SetReplayScore(CreateReplayScore(rulesetContainer.Beatmap)); } @@ -31,5 +27,9 @@ namespace osu.Game.Rulesets.Mods public override double ScoreMultiplier => 1; public bool AllowFail => false; public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail) }; + + public override bool HasImplementation => GetType().GenericTypeArguments.Length == 0; + + public virtual Score CreateReplayScore(IBeatmap beatmap) => new Score { Replay = new Replay() }; } } diff --git a/osu.Game/Rulesets/Replays/AutoGenerator.cs b/osu.Game/Rulesets/Replays/AutoGenerator.cs index efca0a5883..1d4cdbf04c 100644 --- a/osu.Game/Rulesets/Replays/AutoGenerator.cs +++ b/osu.Game/Rulesets/Replays/AutoGenerator.cs @@ -1,14 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Rulesets.Objects; using osu.Game.Beatmaps; using osu.Game.Replays; namespace osu.Game.Rulesets.Replays { - public abstract class AutoGenerator : IAutoGenerator - where T : HitObject + public abstract class AutoGenerator : IAutoGenerator { /// /// Creates the auto replay and returns it. @@ -21,11 +19,11 @@ namespace osu.Game.Rulesets.Replays /// /// The beatmap we're making. /// - protected Beatmap Beatmap; + protected IBeatmap Beatmap; #endregion - protected AutoGenerator(Beatmap beatmap) + protected AutoGenerator(IBeatmap beatmap) { Beatmap = beatmap; } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index ffab0abebf..70f15b99bd 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets /// An enumerable of constructed s public virtual IEnumerable ConvertLegacyMods(LegacyMods mods) => new Mod[] { }; - public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay); + public ModAutoplay GetAutoplayMod() => GetAllMods().OfType().First(); protected Ruleset(RulesetInfo rulesetInfo = null) { From 27edc41c11cc32e6c48bd4fc03188595074331a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Mar 2019 20:14:43 +0900 Subject: [PATCH 49/62] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8f9a7cd14b..882c6ef064 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 499878347b..bc3e553fef 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,12 +105,12 @@ - - + + - + From 340997f505d154eb42d83c60f5f2f4febc903e7d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Mar 2019 20:21:59 +0900 Subject: [PATCH 50/62] Rename remaining usage of PathWidth naming convention --- .../Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs | 4 ++-- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 4 ++-- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index 179fa1bc72..957550a051 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components InternalChild = body = new ManualSliderBody { AccentColour = Color4.Transparent, - PathWidth = slider.Scale * 64 + PathRadius = slider.Scale * 64 }; } @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components body.BorderColour = colours.Yellow; PositionBindable.BindValueChanged(_ => updatePosition(), true); - ScaleBindable.BindValueChanged(scale => body.PathWidth = scale.NewValue * 64, true); + ScaleBindable.BindValueChanged(scale => body.PathRadius = scale.NewValue * 64, true); } private void updatePosition() => Position = slider.StackedPosition; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index ff74954552..57ea0abdd8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { Body = new SnakingSliderBody(s) { - PathWidth = s.Scale * 64, + PathRadius = s.Scale * 64, }, ticks = new Container { RelativeSizeAxes = Axes.Both }, repeatPoints = new Container { RelativeSizeAxes = Axes.Both }, @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables positionBindable.BindValueChanged(_ => Position = HitObject.StackedPosition); scaleBindable.BindValueChanged(scale => { - Body.PathWidth = scale.NewValue * 64; + Body.PathRadius = scale.NewValue * 64; Ball.Scale = new Vector2(scale.NewValue); }); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs index 6f94f5945a..2f5c326bda 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private readonly BufferedContainer container; - public float PathWidth + public float PathRadius { get => path.PathRadius; set => path.PathRadius = value; From cfac47413c36ace948f45e2667fa70d99e9e0fec Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 10:42:25 +0900 Subject: [PATCH 51/62] Disable failing tests temporarily --- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index d5ab0e43d1..a867ddebae 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -113,6 +113,7 @@ namespace osu.Game.Tests.Beatmaps.Formats [TestCase(normal)] [TestCase(marathon)] + [Ignore("temporarily disabled pending DeepEqual fix (https://github.com/jamesfoster/DeepEqual/pull/35)")] // Currently fails: // [TestCase(with_sb)] public void TestParity(string beatmap) From 11e5c6a2a0b4744184b7bcf169dd04e0f9d2f2b4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 12:00:38 +0900 Subject: [PATCH 52/62] Fire initial APIStateChanged on local thread --- osu.Game/Online/API/APIAccess.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 4d039e0b8a..054c57ed75 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -70,13 +70,15 @@ namespace osu.Game.Online.API internal new void Schedule(Action action) => base.Schedule(action); + /// + /// Register a component to receive API events. + /// Fires once immediately to ensure correct . + /// + /// public void Register(IOnlineComponent component) { - Scheduler.Add(delegate - { - components.Add(component); - component.APIStateChanged(this, state); - }); + Scheduler.Add(delegate { components.Add(component); }); + component.APIStateChanged(this, state); } public void Unregister(IOnlineComponent component) From 075ea7012497269314808868c837d4bc181fe70e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 12:01:40 +0900 Subject: [PATCH 53/62] Move more toolbar to async load --- osu.Game/Overlays/Toolbar/Toolbar.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 61b2014af8..a159e21b7a 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Toolbar public Action OnHome; - private readonly ToolbarUserArea userArea; + private ToolbarUserArea userArea; protected override bool BlockPositionalInput => false; @@ -33,7 +33,8 @@ namespace osu.Game.Overlays.Toolbar private readonly Bindable overlayActivationMode = new Bindable(OverlayActivation.All); - public Toolbar() + [BackgroundDependencyLoader(true)] + private void load(OsuGame osuGame) { Children = new Drawable[] { @@ -78,11 +79,7 @@ namespace osu.Game.Overlays.Toolbar RelativeSizeAxes = Axes.X; Size = new Vector2(1, HEIGHT); - } - [BackgroundDependencyLoader(true)] - private void load(OsuGame osuGame) - { StateChanged += visibility => { if (overlayActivationMode.Value == OverlayActivation.Disabled) From d01b026ebd3deb545130d60f05df1f7cc0f52048 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 12:00:12 +0900 Subject: [PATCH 54/62] Fix stuck r# inspection --- osu.Game/Utils/RavenLogger.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Utils/RavenLogger.cs b/osu.Game/Utils/RavenLogger.cs index acc3ab28b5..7f4faa60ae 100644 --- a/osu.Game/Utils/RavenLogger.cs +++ b/osu.Game/Utils/RavenLogger.cs @@ -20,14 +20,14 @@ namespace osu.Game.Utils private readonly List tasks = new List(); - private Exception lastException; - public RavenLogger(OsuGame game) { raven.Release = game.Version; if (!game.IsDeployedBuild) return; + Exception lastException = null; + Logger.NewEntry += entry => { if (entry.Level < LogLevel.Verbose) return; From 345c7f4fa813f19d0b3a97a442719ad930fdec1d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 12:30:52 +0900 Subject: [PATCH 55/62] Fix test regression --- osu.Game.Tests/Visual/TestCaseToolbar.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseToolbar.cs b/osu.Game.Tests/Visual/TestCaseToolbar.cs index be1b75823a..cb5f33911b 100644 --- a/osu.Game.Tests/Visual/TestCaseToolbar.cs +++ b/osu.Game.Tests/Visual/TestCaseToolbar.cs @@ -24,10 +24,13 @@ namespace osu.Game.Tests.Visual public TestCaseToolbar() { var toolbar = new Toolbar { State = Visibility.Visible }; + ToolbarNotificationButton notificationButton = null; - Add(toolbar); - - var notificationButton = toolbar.Children.OfType().Last().Children.OfType().First(); + AddStep("create toolbar", () => + { + Add(toolbar); + notificationButton = toolbar.Children.OfType().Last().Children.OfType().First(); + }); void setNotifications(int count) => AddStep($"set notification count to {count}", () => notificationButton.NotificationCount.Value = count); From 400514630dd33ffee37f579646ea675985167a7d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 12:44:33 +0900 Subject: [PATCH 56/62] Fix incomplete comment --- osu.Game/Online/API/APIAccess.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 054c57ed75..5593abf348 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -72,7 +72,7 @@ namespace osu.Game.Online.API /// /// Register a component to receive API events. - /// Fires once immediately to ensure correct . + /// Fires once immediately to ensure a correct state. /// /// public void Register(IOnlineComponent component) From 2c98ba1c0c875cb0d3d6b031eacf8790a73bad5e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 14:59:45 +0900 Subject: [PATCH 57/62] Split out consumption and creation into two separate code paths --- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 10 ++++++++-- osu.Game/Rulesets/UI/Playfield.cs | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 47a064beee..51733c3c01 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Connections; using osu.Game.Rulesets.UI; using System.Linq; +using osu.Framework.Graphics.Cursor; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.UI.Cursor; @@ -23,6 +24,12 @@ namespace osu.Game.Rulesets.Osu.UI public static readonly Vector2 BASE_SIZE = new Vector2(512, 384); + private readonly PlayfieldAdjustmentContainer adjustmentContainer; + + protected override Container CursorTargetContainer => adjustmentContainer; + + protected override CursorContainer CreateCursor() => new GameplayCursorContainer(); + public OsuPlayfield() { Anchor = Anchor.Centre; @@ -30,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.UI Size = new Vector2(0.75f); - InternalChild = new PlayfieldAdjustmentContainer + InternalChild = adjustmentContainer = new PlayfieldAdjustmentContainer { RelativeSizeAxes = Axes.Both, Children = new Drawable[] @@ -51,7 +58,6 @@ namespace osu.Game.Rulesets.Osu.UI RelativeSizeAxes = Axes.Both, Depth = -1, }, - Cursor = new GameplayCursorContainer(), } }; } diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index f0c2b8859c..2179196d60 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -56,6 +56,10 @@ namespace osu.Game.Rulesets.UI RelativeSizeAxes = Axes.Both; hitObjectContainerLazy = new Lazy(CreateHitObjectContainer); + + Cursor = CreateCursor(); + if (Cursor != null) + CursorTargetContainer.Add(Cursor); } private WorkingBeatmap beatmap; @@ -86,7 +90,19 @@ namespace osu.Game.Rulesets.UI /// /// The cursor currently being used by this . May be null if no cursor is provided. /// - public CursorContainer Cursor { get; protected set; } + public CursorContainer Cursor { get; private set; } + + /// + /// Provide an optional cursor which is to be used for gameplay. + /// If providing a cursor, must also point to a valid target container. + /// + /// The cursor, or null if a cursor is not rqeuired. + protected virtual CursorContainer CreateCursor() => null; + + /// + /// The target container to add the cursor after it is created. + /// + protected virtual Container CursorTargetContainer => null; /// /// Registers a as a nested . From a73e3d9700949d85608dbeb2d00e21a920dacecc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 15:01:45 +0900 Subject: [PATCH 58/62] Move cursor construction to BDL --- osu.Game/Rulesets/UI/Playfield.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 2179196d60..78d14a27e3 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -56,10 +56,6 @@ namespace osu.Game.Rulesets.UI RelativeSizeAxes = Axes.Both; hitObjectContainerLazy = new Lazy(CreateHitObjectContainer); - - Cursor = CreateCursor(); - if (Cursor != null) - CursorTargetContainer.Add(Cursor); } private WorkingBeatmap beatmap; @@ -68,6 +64,10 @@ namespace osu.Game.Rulesets.UI private void load(IBindable beatmap) { this.beatmap = beatmap.Value; + + Cursor = CreateCursor(); + if (Cursor != null) + CursorTargetContainer.Add(Cursor); } /// From 42efea1e06ff2381016107692ec43dcabf920157 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 15:05:45 +0900 Subject: [PATCH 59/62] Apply review --- .../Screens/Play/GameplayClockContainer.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index f769bfd326..594df63420 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Screens.Play { /// - /// Manages the various intricacies of the gameplay clock. + /// Encapsulates gameplay timing logic and provides a for children. /// public class GameplayClockContainer : Container { @@ -35,12 +35,6 @@ namespace osu.Game.Screens.Play /// private readonly DecoupleableInterpolatingFramedClock adjustableClock; - /// - /// The final clock which is exposed to underlying components. - /// - [Cached] - private readonly GameplayClock gameplayClock; - public readonly Bindable UserPlaybackRate = new BindableDouble(1) { Default = 1, @@ -49,16 +43,22 @@ namespace osu.Game.Screens.Play Precision = 0.1, }; + /// + /// The final clock which is exposed to underlying components. + /// + [Cached] + private readonly GameplayClock gameplayClock; + private Bindable userAudioOffset; private readonly FramedOffsetClock offsetClock; public GameplayClockContainer(WorkingBeatmap beatmap, bool allowLeadIn, double gameplayStartTime) { - RelativeSizeAxes = Axes.Both; - this.beatmap = beatmap; + RelativeSizeAxes = Axes.Both; + sourceClock = (IAdjustableClock)beatmap.Track ?? new StopwatchClock(); adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; From 09b5cf48911c66db9a0d3866c5e082bfd3d9f0ec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 8 Mar 2019 15:14:07 +0900 Subject: [PATCH 60/62] Move sizing to ctor --- osu.Game/Overlays/Toolbar/Toolbar.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index a159e21b7a..dca0226499 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -33,6 +33,12 @@ namespace osu.Game.Overlays.Toolbar private readonly Bindable overlayActivationMode = new Bindable(OverlayActivation.All); + public Toolbar() + { + RelativeSizeAxes = Axes.X; + Size = new Vector2(1, HEIGHT); + } + [BackgroundDependencyLoader(true)] private void load(OsuGame osuGame) { @@ -77,9 +83,6 @@ namespace osu.Game.Overlays.Toolbar } }; - RelativeSizeAxes = Axes.X; - Size = new Vector2(1, HEIGHT); - StateChanged += visibility => { if (overlayActivationMode.Value == OverlayActivation.Disabled) From d055b248ac4b04c39100d4c0fe386af45a67a782 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 8 Mar 2019 15:56:36 +0900 Subject: [PATCH 61/62] Remove blank line --- osu.Game/Screens/Play/Player.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c0f4eee895..ced0a43679 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -114,7 +114,6 @@ namespace osu.Game.Screens.Play Start = gameplayClockContainer.Start, Stop = gameplayClockContainer.Stop, IsPaused = { BindTarget = gameplayClockContainer.IsPaused }, - CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded.Value, Children = new[] { From 10734b774c80906f6be301c6c385c13dc2d93750 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Mar 2019 20:48:50 +0900 Subject: [PATCH 62/62] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 882c6ef064..2e945c212d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index bc3e553fef..b25e2a8bb2 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + +