mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 00:23:59 +09:00
Move available mods to global context (#7172)
Move available mods to global context Co-authored-by: Dan Balasescu <smoogipoo@smgi.me>
This commit is contained in:
@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
|
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||||
return base.CreatePlayer(ruleset);
|
return base.CreatePlayer(ruleset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
|
|
||||||
private void addToPlayfield(DrawableCatchHitObject drawable)
|
private void addToPlayfield(DrawableCatchHitObject drawable)
|
||||||
{
|
{
|
||||||
foreach (var mod in Mods.Value.OfType<IApplicableToDrawableHitObjects>())
|
foreach (var mod in SelectedMods.Value.OfType<IApplicableToDrawableHitObjects>())
|
||||||
mod.ApplyToDrawableHitObjects(new[] { drawable });
|
mod.ApplyToDrawableHitObjects(new[] { drawable });
|
||||||
|
|
||||||
drawableRuleset.Playfield.Add(drawable);
|
drawableRuleset.Playfield.Add(drawable);
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
Mods.Value = new[] { new CatchModHidden() };
|
SelectedMods.Value = new[] { new CatchModHidden() };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
var drawable = CreateDrawableHitCircle(circle, auto);
|
var drawable = CreateDrawableHitCircle(circle, auto);
|
||||||
|
|
||||||
foreach (var mod in Mods.Value.OfType<IApplicableToDrawableHitObjects>())
|
foreach (var mod in SelectedMods.Value.OfType<IApplicableToDrawableHitObjects>())
|
||||||
mod.ApplyToDrawableHitObjects(new[] { drawable });
|
mod.ApplyToDrawableHitObjects(new[] { drawable });
|
||||||
|
|
||||||
return drawable;
|
return drawable;
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
Mods.Value = new[] { new OsuModHidden() };
|
SelectedMods.Value = new[] { new OsuModHidden() };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
Mods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), };
|
SelectedMods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), };
|
||||||
|
|
||||||
return base.CreatePlayer(ruleset);
|
return base.CreatePlayer(ruleset);
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
var drawable = CreateDrawableSlider(slider);
|
var drawable = CreateDrawableSlider(slider);
|
||||||
|
|
||||||
foreach (var mod in Mods.Value.OfType<IApplicableToDrawableHitObjects>())
|
foreach (var mod in SelectedMods.Value.OfType<IApplicableToDrawableHitObjects>())
|
||||||
mod.ApplyToDrawableHitObjects(new[] { drawable });
|
mod.ApplyToDrawableHitObjects(new[] { drawable });
|
||||||
|
|
||||||
drawable.OnNewResult += onNewResult;
|
drawable.OnNewResult += onNewResult;
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
Mods.Value = new[] { new OsuModHidden() };
|
SelectedMods.Value = new[] { new OsuModHidden() };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
Depth = depthIndex++
|
Depth = depthIndex++
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var mod in Mods.Value.OfType<IApplicableToDrawableHitObjects>())
|
foreach (var mod in SelectedMods.Value.OfType<IApplicableToDrawableHitObjects>())
|
||||||
mod.ApplyToDrawableHitObjects(new[] { drawable });
|
mod.ApplyToDrawableHitObjects(new[] { drawable });
|
||||||
|
|
||||||
Add(drawable);
|
Add(drawable);
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
Mods.Value = new[] { new OsuModHidden() };
|
SelectedMods.Value = new[] { new OsuModHidden() };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
|
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
Mods.Value = Mods.Value.Concat(new[] { new TaikoModSuddenDeath() }).ToArray();
|
SelectedMods.Value = SelectedMods.Value.Concat(new[] { new TaikoModSuddenDeath() }).ToArray();
|
||||||
return new ScoreAccessiblePlayer();
|
return new ScoreAccessiblePlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
AddUntilStep("Song select has selection", () => songSelect.Carousel.SelectedBeatmap != null);
|
AddUntilStep("Song select has selection", () => songSelect.Carousel.SelectedBeatmap != null);
|
||||||
AddStep("Set default user settings", () =>
|
AddStep("Set default user settings", () =>
|
||||||
{
|
{
|
||||||
Mods.Value = Mods.Value.Concat(new[] { new OsuModNoFail() }).ToArray();
|
SelectedMods.Value = SelectedMods.Value.Concat(new[] { new OsuModNoFail() }).ToArray();
|
||||||
songSelect.DimLevel.Value = 0.7f;
|
songSelect.DimLevel.Value = 0.7f;
|
||||||
songSelect.BlurLevel.Value = 0.4f;
|
songSelect.BlurLevel.Value = 0.4f;
|
||||||
});
|
});
|
||||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||||
return new ScoreAccessiblePlayer();
|
return new ScoreAccessiblePlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
Mods.Value = Array.Empty<Mod>();
|
SelectedMods.Value = Array.Empty<Mod>();
|
||||||
return new FailPlayer();
|
return new FailPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
Mods.Value = Array.Empty<Mod>();
|
SelectedMods.Value = Array.Empty<Mod>();
|
||||||
return new FailPlayer();
|
return new FailPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||||
return new RulesetExposingPlayer();
|
return new RulesetExposingPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
beforeLoadAction?.Invoke();
|
beforeLoadAction?.Invoke();
|
||||||
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||||
|
|
||||||
foreach (var mod in Mods.Value.OfType<IApplicableToTrack>())
|
foreach (var mod in SelectedMods.Value.OfType<IApplicableToTrack>())
|
||||||
mod.ApplyToTrack(Beatmap.Value.Track);
|
mod.ApplyToTrack(Beatmap.Value.Track);
|
||||||
|
|
||||||
InputManager.Child = container = new TestPlayerLoaderContainer(
|
InputManager.Child = container = new TestPlayerLoaderContainer(
|
||||||
@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestEarlyExit()
|
public void TestEarlyExit()
|
||||||
{
|
{
|
||||||
AddStep("load dummy beatmap", () => ResetPlayer(false, () => Mods.Value = new[] { new OsuModNightcore() }));
|
AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() }));
|
||||||
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
|
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
|
||||||
AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1);
|
AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1);
|
||||||
AddStep("exit loader", () => loader.Exit());
|
AddStep("exit loader", () => loader.Exit());
|
||||||
@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
TestMod playerMod1 = null;
|
TestMod playerMod1 = null;
|
||||||
TestMod playerMod2 = null;
|
TestMod playerMod2 = null;
|
||||||
|
|
||||||
AddStep("load player", () => { ResetPlayer(true, () => Mods.Value = new[] { gameMod = new TestMod() }); });
|
AddStep("load player", () => { ResetPlayer(true, () => SelectedMods.Value = new[] { gameMod = new TestMod() }); });
|
||||||
|
|
||||||
AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen());
|
AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen());
|
||||||
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
|
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
|
||||||
|
@ -256,17 +256,17 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("change ruleset", () =>
|
AddStep("change ruleset", () =>
|
||||||
{
|
{
|
||||||
Mods.ValueChanged += onModChange;
|
SelectedMods.ValueChanged += onModChange;
|
||||||
songSelect.Ruleset.ValueChanged += onRulesetChange;
|
songSelect.Ruleset.ValueChanged += onRulesetChange;
|
||||||
|
|
||||||
Ruleset.Value = new TaikoRuleset().RulesetInfo;
|
Ruleset.Value = new TaikoRuleset().RulesetInfo;
|
||||||
|
|
||||||
Mods.ValueChanged -= onModChange;
|
SelectedMods.ValueChanged -= onModChange;
|
||||||
songSelect.Ruleset.ValueChanged -= onRulesetChange;
|
songSelect.Ruleset.ValueChanged -= onRulesetChange;
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex);
|
AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex);
|
||||||
AddAssert("empty mods", () => !Mods.Value.Any());
|
AddAssert("empty mods", () => !SelectedMods.Value.Any());
|
||||||
|
|
||||||
void onModChange(ValueChangedEvent<IReadOnlyList<Mod>> e) => modChangeIndex = actionIndex++;
|
void onModChange(ValueChangedEvent<IReadOnlyList<Mod>> e) => modChangeIndex = actionIndex++;
|
||||||
void onRulesetChange(ValueChangedEvent<RulesetInfo> e) => rulesetChangeIndex = actionIndex++;
|
void onRulesetChange(ValueChangedEvent<RulesetInfo> e) => rulesetChangeIndex = actionIndex++;
|
||||||
@ -275,7 +275,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestModsRetainedBetweenSongSelect()
|
public void TestModsRetainedBetweenSongSelect()
|
||||||
{
|
{
|
||||||
AddAssert("empty mods", () => !Mods.Value.Any());
|
AddAssert("empty mods", () => !SelectedMods.Value.Any());
|
||||||
|
|
||||||
createSongSelect();
|
createSongSelect();
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
createSongSelect();
|
createSongSelect();
|
||||||
|
|
||||||
AddAssert("mods retained", () => Mods.Value.Any());
|
AddAssert("mods retained", () => SelectedMods.Value.Any());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -332,7 +332,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
private void checkMusicPlaying(bool playing) =>
|
private void checkMusicPlaying(bool playing) =>
|
||||||
AddUntilStep($"music {(playing ? "" : "not ")}playing", () => music.IsPlaying == playing);
|
AddUntilStep($"music {(playing ? "" : "not ")}playing", () => music.IsPlaying == playing);
|
||||||
|
|
||||||
private void changeMods(params Mod[] mods) => AddStep($"change mods to {string.Join(", ", mods.Select(m => m.Acronym))}", () => Mods.Value = mods);
|
private void changeMods(params Mod[] mods) => AddStep($"change mods to {string.Join(", ", mods.Select(m => m.Acronym))}", () => SelectedMods.Value = mods);
|
||||||
|
|
||||||
private void changeRuleset(int id) => AddStep($"change ruleset to {id}", () => Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == id));
|
private void changeRuleset(int id) => AddStep($"change ruleset to {id}", () => Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == id));
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
var noFailMod = new OsuRuleset().GetModsFor(ModType.DifficultyReduction).FirstOrDefault(m => m is OsuModNoFail);
|
var noFailMod = new OsuRuleset().GetModsFor(ModType.DifficultyReduction).FirstOrDefault(m => m is OsuModNoFail);
|
||||||
|
|
||||||
AddStep("set mods externally", () => { Mods.Value = new[] { noFailMod }; });
|
AddStep("set mods externally", () => { SelectedMods.Value = new[] { noFailMod }; });
|
||||||
|
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
|
|
||||||
|
@ -2,15 +2,20 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Mods;
|
using osu.Game.Overlays.Mods;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.UserInterface
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
{
|
{
|
||||||
@ -18,26 +23,49 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
private TestModSelectOverlay modSelect;
|
private TestModSelectOverlay modSelect;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
private readonly Mod testCustomisableMod = new TestModCustomisable1();
|
||||||
private void load()
|
|
||||||
|
[Test]
|
||||||
|
public void TestButtonShowsOnCustomisableMod()
|
||||||
{
|
{
|
||||||
Add(modSelect = new TestModSelectOverlay
|
createModSelect();
|
||||||
|
|
||||||
|
AddStep("open", () => modSelect.Show());
|
||||||
|
AddAssert("button disabled", () => !modSelect.CustomiseButton.Enabled.Value);
|
||||||
|
AddUntilStep("wait for button load", () => modSelect.ButtonsLoaded);
|
||||||
|
AddStep("select mod", () => modSelect.SelectMod(testCustomisableMod));
|
||||||
|
AddAssert("button enabled", () => modSelect.CustomiseButton.Enabled.Value);
|
||||||
|
AddStep("open Customisation", () => modSelect.CustomiseButton.Click());
|
||||||
|
AddStep("deselect mod", () => modSelect.SelectMod(testCustomisableMod));
|
||||||
|
AddAssert("controls hidden", () => modSelect.ModSettingsContainer.Alpha == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestButtonShowsOnModAlreadyAdded()
|
||||||
|
{
|
||||||
|
AddStep("set active mods", () => SelectedMods.Value = new List<Mod> { testCustomisableMod });
|
||||||
|
|
||||||
|
createModSelect();
|
||||||
|
|
||||||
|
AddAssert("mods still active", () => SelectedMods.Value.Count == 1);
|
||||||
|
|
||||||
|
AddStep("open", () => modSelect.Show());
|
||||||
|
AddAssert("button enabled", () => modSelect.CustomiseButton.Enabled.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createModSelect()
|
||||||
|
{
|
||||||
|
AddStep("create mod select", () =>
|
||||||
|
{
|
||||||
|
Ruleset.Value = new TestRulesetInfo();
|
||||||
|
|
||||||
|
Child = modSelect = new TestModSelectOverlay
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Origin = Anchor.BottomCentre,
|
Origin = Anchor.BottomCentre,
|
||||||
Anchor = Anchor.BottomCentre,
|
Anchor = Anchor.BottomCentre,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
var testMod = new TestModCustomisable1();
|
|
||||||
|
|
||||||
AddStep("open", modSelect.Show);
|
|
||||||
AddAssert("button disabled", () => !modSelect.CustomiseButton.Enabled.Value);
|
|
||||||
AddUntilStep("wait for button load", () => modSelect.ButtonsLoaded);
|
|
||||||
AddStep("select mod", () => modSelect.SelectMod(testMod));
|
|
||||||
AddAssert("button enabled", () => modSelect.CustomiseButton.Enabled.Value);
|
|
||||||
AddStep("open Customisation", () => modSelect.CustomiseButton.Click());
|
|
||||||
AddStep("deselect mod", () => modSelect.SelectMod(testMod));
|
|
||||||
AddAssert("controls hidden", () => modSelect.ModSettingsContainer.Alpha == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestModSelectOverlay : ModSelectOverlay
|
private class TestModSelectOverlay : ModSelectOverlay
|
||||||
@ -50,24 +78,36 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
public void SelectMod(Mod mod) =>
|
public void SelectMod(Mod mod) =>
|
||||||
ModSectionsContainer.Children.Single(s => s.ModType == mod.Type)
|
ModSectionsContainer.Children.Single(s => s.ModType == mod.Type)
|
||||||
.ButtonsContainer.OfType<ModButton>().Single(b => b.Mods.Any(m => m.GetType() == mod.GetType())).SelectNext(1);
|
.ButtonsContainer.OfType<ModButton>().Single(b => b.Mods.Any(m => m.GetType() == mod.GetType())).SelectNext(1);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
public class TestRulesetInfo : RulesetInfo
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
public override Ruleset CreateInstance() => new TestCustomisableModRuleset();
|
||||||
|
|
||||||
foreach (var section in ModSectionsContainer)
|
public class TestCustomisableModRuleset : Ruleset
|
||||||
{
|
{
|
||||||
if (section.ModType == ModType.Conversion)
|
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||||
{
|
{
|
||||||
section.Mods = new Mod[]
|
if (type == ModType.Conversion)
|
||||||
|
{
|
||||||
|
return new Mod[]
|
||||||
{
|
{
|
||||||
new TestModCustomisable1(),
|
new TestModCustomisable1(),
|
||||||
new TestModCustomisable2()
|
new TestModCustomisable2()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
|
||||||
section.Mods = Array.Empty<Mod>();
|
return Array.Empty<Mod>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override string Description { get; } = "test";
|
||||||
|
public override string ShortName { get; } = "tst";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,12 @@ namespace osu.Game
|
|||||||
// todo: move this to SongSelect once Screen has the ability to unsuspend.
|
// todo: move this to SongSelect once Screen has the ability to unsuspend.
|
||||||
[Cached]
|
[Cached]
|
||||||
[Cached(typeof(IBindable<IReadOnlyList<Mod>>))]
|
[Cached(typeof(IBindable<IReadOnlyList<Mod>>))]
|
||||||
protected readonly Bindable<IReadOnlyList<Mod>> Mods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
protected readonly Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mods available for the current <see cref="Ruleset"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> AvailableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
|
||||||
|
|
||||||
protected Bindable<WorkingBeatmap> Beatmap { get; private set; } // cached via load() method
|
protected Bindable<WorkingBeatmap> Beatmap { get; private set; } // cached via load() method
|
||||||
|
|
||||||
@ -233,6 +238,19 @@ namespace osu.Game
|
|||||||
PreviewTrackManager previewTrackManager;
|
PreviewTrackManager previewTrackManager;
|
||||||
dependencies.Cache(previewTrackManager = new PreviewTrackManager());
|
dependencies.Cache(previewTrackManager = new PreviewTrackManager());
|
||||||
Add(previewTrackManager);
|
Add(previewTrackManager);
|
||||||
|
|
||||||
|
Ruleset.BindValueChanged(onRulesetChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRulesetChanged(ValueChangedEvent<RulesetInfo> r)
|
||||||
|
{
|
||||||
|
var dict = new Dictionary<ModType, IReadOnlyList<Mod>>();
|
||||||
|
|
||||||
|
foreach (ModType type in Enum.GetValues(typeof(ModType)))
|
||||||
|
dict[type] = r.NewValue?.CreateInstance().GetModsFor(type).ToList();
|
||||||
|
|
||||||
|
SelectedMods.Value = Array.Empty<Mod>();
|
||||||
|
AvailableMods.Value = dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Container CreateScalingContainer() => new DrawSizePreservingFillContainer();
|
protected virtual Container CreateScalingContainer() => new DrawSizePreservingFillContainer();
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -12,14 +12,13 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Overlays.Mods
|
namespace osu.Game.Overlays.Mods
|
||||||
{
|
{
|
||||||
public class ModControlSection : Container
|
public class ModControlSection : CompositeDrawable
|
||||||
{
|
{
|
||||||
protected FillFlowContainer FlowContent;
|
protected FillFlowContainer FlowContent;
|
||||||
protected override Container<Drawable> Content => FlowContent;
|
|
||||||
|
|
||||||
public readonly Mod Mod;
|
public readonly Mod Mod;
|
||||||
|
|
||||||
public ModControlSection(Mod mod)
|
public ModControlSection(Mod mod, IEnumerable<Drawable> modControls)
|
||||||
{
|
{
|
||||||
Mod = mod;
|
Mod = mod;
|
||||||
|
|
||||||
@ -33,9 +32,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
|
ChildrenEnumerable = modControls
|
||||||
};
|
};
|
||||||
|
|
||||||
AddRange(Mod.CreateSettingsControls());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -20,7 +20,6 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Mods.Sections;
|
using osu.Game.Overlays.Mods.Sections;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -50,7 +49,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
protected readonly Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
protected readonly Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
||||||
|
|
||||||
protected readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
private Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods;
|
||||||
|
|
||||||
protected Color4 LowMultiplierColour;
|
protected Color4 LowMultiplierColour;
|
||||||
protected Color4 HighMultiplierColour;
|
protected Color4 HighMultiplierColour;
|
||||||
@ -322,14 +321,14 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IReadOnlyList<Mod>> mods)
|
private void load(OsuColour colours, AudioManager audio, Bindable<IReadOnlyList<Mod>> selectedMods, OsuGameBase osu)
|
||||||
{
|
{
|
||||||
LowMultiplierColour = colours.Red;
|
LowMultiplierColour = colours.Red;
|
||||||
HighMultiplierColour = colours.Green;
|
HighMultiplierColour = colours.Green;
|
||||||
UnrankedLabel.Colour = colours.Blue;
|
UnrankedLabel.Colour = colours.Blue;
|
||||||
|
|
||||||
Ruleset.BindTo(ruleset);
|
availableMods = osu.AvailableMods.GetBoundCopy();
|
||||||
if (mods != null) SelectedMods.BindTo(mods);
|
SelectedMods.BindTo(selectedMods);
|
||||||
|
|
||||||
sampleOn = audio.Samples.Get(@"UI/check-on");
|
sampleOn = audio.Samples.Get(@"UI/check-on");
|
||||||
sampleOff = audio.Samples.Get(@"UI/check-off");
|
sampleOff = audio.Samples.Get(@"UI/check-off");
|
||||||
@ -360,7 +359,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
Ruleset.BindValueChanged(rulesetChanged, true);
|
availableMods.BindValueChanged(availableModsChanged, true);
|
||||||
SelectedMods.BindValueChanged(selectedModsChanged, true);
|
SelectedMods.BindValueChanged(selectedModsChanged, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,22 +409,12 @@ namespace osu.Game.Overlays.Mods
|
|||||||
return base.OnKeyDown(e);
|
return base.OnKeyDown(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e)
|
private void availableModsChanged(ValueChangedEvent<Dictionary<ModType, IReadOnlyList<Mod>>> mods)
|
||||||
{
|
{
|
||||||
if (e.NewValue == null) return;
|
if (mods.NewValue == null) return;
|
||||||
|
|
||||||
var instance = e.NewValue.CreateInstance();
|
|
||||||
|
|
||||||
foreach (var section in ModSectionsContainer.Children)
|
foreach (var section in ModSectionsContainer.Children)
|
||||||
section.Mods = instance.GetModsFor(section.ModType);
|
section.Mods = mods.NewValue[section.ModType];
|
||||||
|
|
||||||
// attempt to re-select any already selected mods.
|
|
||||||
// this may be the first time we are receiving the ruleset, in which case they will still match.
|
|
||||||
selectedModsChanged(new ValueChangedEvent<IReadOnlyList<Mod>>(SelectedMods.Value, SelectedMods.Value));
|
|
||||||
|
|
||||||
// write the mods back to the SelectedMods bindable in the case a change was not applicable.
|
|
||||||
// this generally isn't required as the previous line will perform deselection; just here for safety.
|
|
||||||
refreshSelectedMods();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
||||||
@ -462,17 +451,17 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
private void updateModSettings(ValueChangedEvent<IReadOnlyList<Mod>> selectedMods)
|
private void updateModSettings(ValueChangedEvent<IReadOnlyList<Mod>> selectedMods)
|
||||||
{
|
{
|
||||||
foreach (var added in selectedMods.NewValue.Except(selectedMods.OldValue))
|
ModSettingsContent.Clear();
|
||||||
|
|
||||||
|
foreach (var mod in selectedMods.NewValue)
|
||||||
{
|
{
|
||||||
var controls = added.CreateSettingsControls().ToList();
|
var settings = mod.CreateSettingsControls().ToList();
|
||||||
if (controls.Count > 0)
|
if (settings.Count > 0)
|
||||||
ModSettingsContent.Add(new ModControlSection(added) { Children = controls });
|
ModSettingsContent.Add(new ModControlSection(mod, settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var removed in selectedMods.OldValue.Except(selectedMods.NewValue))
|
bool hasSettings = ModSettingsContent.Count > 0;
|
||||||
ModSettingsContent.RemoveAll(section => section.Mod == removed);
|
|
||||||
|
|
||||||
bool hasSettings = ModSettingsContent.Children.Count > 0;
|
|
||||||
CustomiseButton.Enabled.Value = hasSettings;
|
CustomiseButton.Enabled.Value = hasSettings;
|
||||||
|
|
||||||
if (!hasSettings)
|
if (!hasSettings)
|
||||||
@ -502,8 +491,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
Ruleset.UnbindAll();
|
availableMods?.UnbindAll();
|
||||||
SelectedMods.UnbindAll();
|
SelectedMods?.UnbindAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
var working = CreateWorkingBeatmap(rulesetInfo);
|
var working = CreateWorkingBeatmap(rulesetInfo);
|
||||||
|
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) };
|
SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) };
|
||||||
|
|
||||||
Player?.Exit();
|
Player?.Exit();
|
||||||
Player = null;
|
Player = null;
|
||||||
|
@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
protected Bindable<RulesetInfo> Ruleset;
|
protected Bindable<RulesetInfo> Ruleset;
|
||||||
|
|
||||||
protected Bindable<IReadOnlyList<Mod>> Mods;
|
protected Bindable<IReadOnlyList<Mod>> SelectedMods;
|
||||||
|
|
||||||
protected new OsuScreenDependencies Dependencies { get; private set; }
|
protected new OsuScreenDependencies Dependencies { get; private set; }
|
||||||
|
|
||||||
@ -72,8 +72,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
Ruleset = Dependencies.Ruleset;
|
Ruleset = Dependencies.Ruleset;
|
||||||
Ruleset.SetDefault();
|
Ruleset.SetDefault();
|
||||||
|
|
||||||
Mods = Dependencies.Mods;
|
SelectedMods = Dependencies.Mods;
|
||||||
Mods.SetDefault();
|
SelectedMods.SetDefault();
|
||||||
|
|
||||||
if (!UseOnlineAPI)
|
if (!UseOnlineAPI)
|
||||||
{
|
{
|
||||||
|
@ -53,14 +53,14 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
var noFailMod = ruleset.GetAllMods().FirstOrDefault(m => m is ModNoFail);
|
var noFailMod = ruleset.GetAllMods().FirstOrDefault(m => m is ModNoFail);
|
||||||
if (noFailMod != null)
|
if (noFailMod != null)
|
||||||
Mods.Value = new[] { noFailMod };
|
SelectedMods.Value = new[] { noFailMod };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Autoplay)
|
if (Autoplay)
|
||||||
{
|
{
|
||||||
var mod = ruleset.GetAutoplayMod();
|
var mod = ruleset.GetAutoplayMod();
|
||||||
if (mod != null)
|
if (mod != null)
|
||||||
Mods.Value = Mods.Value.Concat(mod.Yield()).ToArray();
|
SelectedMods.Value = SelectedMods.Value.Concat(mod.Yield()).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
Player = CreatePlayer(ruleset);
|
Player = CreatePlayer(ruleset);
|
||||||
|
Reference in New Issue
Block a user