mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 09:27:29 +08:00
Added a way for mod settings to be kept when changing ruleset + test
This commit is contained in:
parent
ee87a29376
commit
191604340f
@ -21,6 +21,7 @@ using osu.Game.Rulesets.Catch.Mods;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.Taiko.Mods;
|
||||
using osu.Game.Tests.Mods;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
@ -371,6 +372,53 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
AddAssert("no mod selected", () => SelectedMods.Value.Count == 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestKeepSharedSettingsFromSimilarMods()
|
||||
{
|
||||
const float setting_change = 1.2f;
|
||||
|
||||
createScreen();
|
||||
changeRuleset(0);
|
||||
|
||||
AddStep("select difficulty adjust mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod<ModDifficultyAdjust>()! });
|
||||
|
||||
changeRuleset(0);
|
||||
AddAssert("ensure mod still selected", () => SelectedMods.Value.SingleOrDefault() is OsuModDifficultyAdjust);
|
||||
|
||||
AddStep("change mod settings", () =>
|
||||
{
|
||||
var osuMod = (getMod() as OsuModDifficultyAdjust)!;
|
||||
osuMod.ExtendedLimits.Value = true;
|
||||
osuMod.CircleSize.Value = setting_change;
|
||||
osuMod.DrainRate.Value = setting_change;
|
||||
osuMod.OverallDifficulty.Value = setting_change;
|
||||
osuMod.ApproachRate.Value = setting_change;
|
||||
});
|
||||
|
||||
changeRuleset(1);
|
||||
AddAssert("taiko variant selected", () => SelectedMods.Value.SingleOrDefault() is TaikoModDifficultyAdjust);
|
||||
|
||||
AddAssert("shared settings didn't change", () =>
|
||||
{
|
||||
var taikoMod = getMod() as TaikoModDifficultyAdjust;
|
||||
return
|
||||
taikoMod?.ExtendedLimits.Value == true &&
|
||||
taikoMod?.DrainRate.Value == setting_change &&
|
||||
taikoMod?.OverallDifficulty.Value == setting_change;
|
||||
});
|
||||
|
||||
AddAssert("non-shared settings at default", () =>
|
||||
{
|
||||
var taikoMod = getMod() as TaikoModDifficultyAdjust;
|
||||
if (taikoMod == null)
|
||||
return false;
|
||||
|
||||
return taikoMod.ScrollSpeed.Value == taikoMod.ScrollSpeed.Default;
|
||||
});
|
||||
|
||||
ModDifficultyAdjust getMod() => (SelectedMods.Value.Single() as ModDifficultyAdjust)!;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestExternallySetCustomizedMod()
|
||||
{
|
||||
|
@ -393,8 +393,11 @@ namespace osu.Game
|
||||
|
||||
Ruleset.BindValueChanged(onRulesetChanged);
|
||||
Beatmap.BindValueChanged(onBeatmapChanged);
|
||||
SelectedMods.BindValueChanged(change => Logger.Log($"{modSetting(change.OldValue)} => {modSetting(change.NewValue)}"));
|
||||
}
|
||||
|
||||
private object modSetting(IReadOnlyList<Mod> mods) => mods.OfType<ModDoubleTime>().FirstOrDefault()?.GetSettingsSourceProperties().First().Item2.GetValue(mods.OfType<ModDoubleTime>().First())!;
|
||||
|
||||
private void addFilesWarning()
|
||||
{
|
||||
var realmStore = new RealmFileStore(realm, Storage);
|
||||
@ -626,7 +629,8 @@ namespace osu.Game
|
||||
return;
|
||||
}
|
||||
|
||||
var previouslySelectedMods = SelectedMods.Value.ToArray();
|
||||
//for some reason emptying SelectedMods resets all SettingSources Bindables to default value
|
||||
var previouslySelectedMods = SelectedMods.Value.Select(mod => mod.DeepClone()).ToArray();
|
||||
|
||||
if (!SelectedMods.Disabled)
|
||||
SelectedMods.Value = Array.Empty<Mod>();
|
||||
@ -634,7 +638,16 @@ namespace osu.Game
|
||||
AvailableMods.Value = dict;
|
||||
|
||||
if (!SelectedMods.Disabled)
|
||||
SelectedMods.Value = previouslySelectedMods.Select(m => instance.CreateModFromAcronym(m.Acronym)).Where(m => m != null).ToArray();
|
||||
{
|
||||
SelectedMods.Value = previouslySelectedMods.Select(oldMod =>
|
||||
{
|
||||
Mod newMod = instance.CreateModFromAcronym(oldMod.Acronym);
|
||||
|
||||
newMod?.CopyFromSimilar(oldMod);
|
||||
|
||||
return newMod;
|
||||
}).Where(m => m != null).ToArray();
|
||||
}
|
||||
|
||||
void revertRulesetChange() => Ruleset.Value = r.OldValue?.Available == true ? r.OldValue : RulesetStore.AvailableRulesets.First();
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Utils;
|
||||
|
||||
@ -139,6 +140,30 @@ namespace osu.Game.Rulesets.Mods
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies all shared mod setting values from <paramref name="source"/> into this instance.
|
||||
/// </summary>
|
||||
/// <param name="source">The mod to copy properties from.</param>
|
||||
public void CopyFromSimilar(Mod source)
|
||||
{
|
||||
Dictionary<string, object> oldSettings = new Dictionary<string, object>();
|
||||
|
||||
foreach (var (_, property) in source.GetSettingsSourceProperties())
|
||||
{
|
||||
oldSettings.Add(property.Name.ToSnakeCase(), property.GetValue(source)!);
|
||||
}
|
||||
|
||||
foreach (var (_, property) in this.GetSettingsSourceProperties())
|
||||
{
|
||||
var targetBindable = (IBindable)property.GetValue(this)!;
|
||||
|
||||
if (!oldSettings.TryGetValue(property.Name.ToSnakeCase(), out object? sourceSetting))
|
||||
continue;
|
||||
|
||||
CopyAdjustedSetting(targetBindable, sourceSetting);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies mod setting values from <paramref name="source"/> into this instance, overwriting all existing settings.
|
||||
/// </summary>
|
||||
@ -148,10 +173,10 @@ namespace osu.Game.Rulesets.Mods
|
||||
if (source.GetType() != GetType())
|
||||
throw new ArgumentException($"Expected mod of type {GetType()}, got {source.GetType()}.", nameof(source));
|
||||
|
||||
foreach (var (_, prop) in this.GetSettingsSourceProperties())
|
||||
foreach (var (_, property) in this.GetSettingsSourceProperties())
|
||||
{
|
||||
var targetBindable = (IBindable)prop.GetValue(this)!;
|
||||
var sourceBindable = (IBindable)prop.GetValue(source)!;
|
||||
var targetBindable = (IBindable)property.GetValue(this)!;
|
||||
var sourceBindable = (IBindable)property.GetValue(source)!;
|
||||
|
||||
CopyAdjustedSetting(targetBindable, sourceBindable);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user