mirror of
https://github.com/osukey/osukey.git
synced 2025-04-29 02:37:25 +09:00
Merge branch 'master' into fix-catch-clamp
This commit is contained in:
commit
cc21e42e35
@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestSkin : DefaultSkin
|
private class TestSkin : TrianglesSkin
|
||||||
{
|
{
|
||||||
public bool FlipCatcherPlate { get; set; }
|
public bool FlipCatcherPlate { get; set; }
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(SkinManager skins)
|
private void load(SkinManager skins)
|
||||||
{
|
{
|
||||||
var defaultLegacySkin = skins.DefaultLegacySkin;
|
var defaultLegacySkin = skins.DefaultClassicSkin;
|
||||||
|
|
||||||
// sprite names intentionally swapped to match stable member naming / ease of cross-referencing
|
// sprite names intentionally swapped to match stable member naming / ease of cross-referencing
|
||||||
explosion1.Texture = defaultLegacySkin.GetTexture("scoreboard-explosion-2");
|
explosion1.Texture = defaultLegacySkin.GetTexture("scoreboard-explosion-2");
|
||||||
|
@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestDefaultSkin()
|
public void TestDefaultSkin()
|
||||||
{
|
{
|
||||||
AddStep("set default skin", () => skins.CurrentSkinInfo.Value = DefaultSkin.CreateInfo().ToLiveUnmanaged());
|
AddStep("set default skin", () => skins.CurrentSkinInfo.Value = TrianglesSkin.CreateInfo().ToLiveUnmanaged());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
});
|
});
|
||||||
AddStep("setup default legacy skin", () =>
|
AddStep("setup default legacy skin", () =>
|
||||||
{
|
{
|
||||||
skinManager.CurrentSkinInfo.Value = skinManager.DefaultLegacySkin.SkinInfo;
|
skinManager.CurrentSkinInfo.Value = skinManager.DefaultClassicSkin.SkinInfo;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
|
|
||||||
Child = new SkinProvidingContainer(new DefaultSkin(null))
|
Child = new SkinProvidingContainer(new TrianglesSkin(null))
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Child = drawableHitCircle = new DrawableHitCircle(hitCircle)
|
Child = drawableHitCircle = new DrawableHitCircle(hitCircle)
|
||||||
|
@ -44,6 +44,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
|
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
|
||||||
|
|
||||||
|
if (mods.Any(m => m is OsuModTouchDevice))
|
||||||
|
{
|
||||||
|
aimRating = Math.Pow(aimRating, 0.8);
|
||||||
|
flashlightRating = Math.Pow(flashlightRating, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
if (mods.Any(h => h is OsuModRelax))
|
if (mods.Any(h => h is OsuModRelax))
|
||||||
{
|
{
|
||||||
aimRating *= 0.9;
|
aimRating *= 0.9;
|
||||||
@ -127,6 +133,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
protected override Mod[] DifficultyAdjustmentMods => new Mod[]
|
protected override Mod[] DifficultyAdjustmentMods => new Mod[]
|
||||||
{
|
{
|
||||||
|
new OsuModTouchDevice(),
|
||||||
new OsuModDoubleTime(),
|
new OsuModDoubleTime(),
|
||||||
new OsuModHalfTime(),
|
new OsuModHalfTime(),
|
||||||
new OsuModEasy(),
|
new OsuModEasy(),
|
||||||
|
@ -88,12 +88,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
private double computeAimValue(ScoreInfo score, OsuDifficultyAttributes attributes)
|
private double computeAimValue(ScoreInfo score, OsuDifficultyAttributes attributes)
|
||||||
{
|
{
|
||||||
double rawAim = attributes.AimDifficulty;
|
double aimValue = Math.Pow(5.0 * Math.Max(1.0, attributes.AimDifficulty / 0.0675) - 4.0, 3.0) / 100000.0;
|
||||||
|
|
||||||
if (score.Mods.Any(m => m is OsuModTouchDevice))
|
|
||||||
rawAim = Math.Pow(rawAim, 0.8);
|
|
||||||
|
|
||||||
double aimValue = Math.Pow(5.0 * Math.Max(1.0, rawAim / 0.0675) - 4.0, 3.0) / 100000.0;
|
|
||||||
|
|
||||||
double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
|
double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
|
||||||
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
|
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
|
||||||
@ -233,12 +228,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
if (!score.Mods.Any(h => h is OsuModFlashlight))
|
if (!score.Mods.Any(h => h is OsuModFlashlight))
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
double rawFlashlight = attributes.FlashlightDifficulty;
|
double flashlightValue = Math.Pow(attributes.FlashlightDifficulty, 2.0) * 25.0;
|
||||||
|
|
||||||
if (score.Mods.Any(m => m is OsuModTouchDevice))
|
|
||||||
rawFlashlight = Math.Pow(rawFlashlight, 0.8);
|
|
||||||
|
|
||||||
double flashlightValue = Math.Pow(rawFlashlight, 2.0) * 25.0;
|
|
||||||
|
|
||||||
// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
|
// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
|
||||||
if (effectiveMissCount > 0)
|
if (effectiveMissCount > 0)
|
||||||
|
@ -306,7 +306,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
new Color4(128, 255, 128, 255),
|
new Color4(128, 255, 128, 255),
|
||||||
new Color4(255, 187, 255, 255),
|
new Color4(255, 187, 255, 255),
|
||||||
new Color4(255, 177, 140, 255),
|
new Color4(255, 177, 140, 255),
|
||||||
new Color4(100, 100, 100, 100),
|
new Color4(100, 100, 100, 255), // alpha is specified as 100, but should be ignored.
|
||||||
};
|
};
|
||||||
Assert.AreEqual(expectedColors.Length, comboColors.Count);
|
Assert.AreEqual(expectedColors.Length, comboColors.Count);
|
||||||
for (int i = 0; i < expectedColors.Length; i++)
|
for (int i = 0; i < expectedColors.Length; i++)
|
||||||
|
@ -202,7 +202,7 @@ namespace osu.Game.Tests.Skins.IO
|
|||||||
skinManager.CurrentSkinInfo.Value.PerformRead(s =>
|
skinManager.CurrentSkinInfo.Value.PerformRead(s =>
|
||||||
{
|
{
|
||||||
Assert.IsFalse(s.Protected);
|
Assert.IsFalse(s.Protected);
|
||||||
Assert.AreEqual(typeof(DefaultSkin), s.CreateInstance(skinManager).GetType());
|
Assert.AreEqual(typeof(TrianglesSkin), s.CreateInstance(skinManager).GetType());
|
||||||
|
|
||||||
new LegacySkinExporter(osu.Dependencies.Get<Storage>()).ExportModelTo(s, exportStream);
|
new LegacySkinExporter(osu.Dependencies.Get<Storage>()).ExportModelTo(s, exportStream);
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ namespace osu.Game.Tests.Skins.IO
|
|||||||
{
|
{
|
||||||
Assert.IsFalse(s.Protected);
|
Assert.IsFalse(s.Protected);
|
||||||
Assert.AreNotEqual(originalSkinId, s.ID);
|
Assert.AreNotEqual(originalSkinId, s.ID);
|
||||||
Assert.AreEqual(typeof(DefaultSkin), s.CreateInstance(skinManager).GetType());
|
Assert.AreEqual(typeof(TrianglesSkin), s.CreateInstance(skinManager).GetType());
|
||||||
});
|
});
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@ -226,7 +226,7 @@ namespace osu.Game.Tests.Skins.IO
|
|||||||
{
|
{
|
||||||
var skinManager = osu.Dependencies.Get<SkinManager>();
|
var skinManager = osu.Dependencies.Get<SkinManager>();
|
||||||
|
|
||||||
skinManager.CurrentSkinInfo.Value = skinManager.DefaultLegacySkin.SkinInfo;
|
skinManager.CurrentSkinInfo.Value = skinManager.DefaultClassicSkin.SkinInfo;
|
||||||
|
|
||||||
skinManager.EnsureMutableSkin();
|
skinManager.EnsureMutableSkin();
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Tests.Skins
|
|||||||
new Color4(142, 199, 255, 255),
|
new Color4(142, 199, 255, 255),
|
||||||
new Color4(255, 128, 128, 255),
|
new Color4(255, 128, 128, 255),
|
||||||
new Color4(128, 255, 255, 255),
|
new Color4(128, 255, 255, 255),
|
||||||
new Color4(100, 100, 100, 100),
|
new Color4(100, 100, 100, 255), // alpha is specified as 100, but should be ignored.
|
||||||
};
|
};
|
||||||
|
|
||||||
Assert.AreEqual(expectedColors.Count, comboColors.Count);
|
Assert.AreEqual(expectedColors.Count, comboColors.Count);
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
@ -19,7 +18,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
SetContents(skin =>
|
SetContents(skin =>
|
||||||
{
|
{
|
||||||
var implementation = skin != null
|
var implementation = skin is LegacySkin
|
||||||
? CreateLegacyImplementation()
|
? CreateLegacyImplementation()
|
||||||
: CreateDefaultImplementation();
|
: CreateDefaultImplementation();
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestEmptyLegacyBeatmapSkinFallsBack()
|
public void TestEmptyLegacyBeatmapSkinFallsBack()
|
||||||
{
|
{
|
||||||
CreateSkinTest(DefaultSkin.CreateInfo(), () => new LegacyBeatmapSkin(new BeatmapInfo(), null));
|
CreateSkinTest(TrianglesSkin.CreateInfo(), () => new LegacyBeatmapSkin(new BeatmapInfo(), null));
|
||||||
AddUntilStep("wait for hud load", () => Player.ChildrenOfType<SkinnableTargetContainer>().All(c => c.ComponentsLoaded));
|
AddUntilStep("wait for hud load", () => Player.ChildrenOfType<SkinnableTargetContainer>().All(c => c.ComponentsLoaded));
|
||||||
AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(SkinnableTarget.MainHUDComponents, skinManager.CurrentSkin.Value));
|
AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(SkinnableTarget.MainHUDComponents, skinManager.CurrentSkin.Value));
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TestParticleSpewer createSpewer() =>
|
private TestParticleSpewer createSpewer() =>
|
||||||
new TestParticleSpewer(skinManager.DefaultLegacySkin.GetTexture("star2"))
|
new TestParticleSpewer(skinManager.DefaultClassicSkin.GetTexture("star2"))
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativePositionAxes = Axes.Both,
|
RelativePositionAxes = Axes.Both,
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestEditDefaultSkin()
|
public void TestEditDefaultSkin()
|
||||||
{
|
{
|
||||||
AddAssert("is default skin", () => skinManager.CurrentSkinInfo.Value.ID == SkinInfo.DEFAULT_SKIN);
|
AddAssert("is default skin", () => skinManager.CurrentSkinInfo.Value.ID == SkinInfo.TRIANGLES_SKIN);
|
||||||
|
|
||||||
AddStep("open settings", () => { Game.Settings.Show(); });
|
AddStep("open settings", () => { Game.Settings.Show(); });
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
AddStep("open skin editor", () => skinEditor.Show());
|
AddStep("open skin editor", () => skinEditor.Show());
|
||||||
|
|
||||||
// Until step required as the skin editor may take time to load (and an extra scheduled frame for the mutable part).
|
// Until step required as the skin editor may take time to load (and an extra scheduled frame for the mutable part).
|
||||||
AddUntilStep("is modified default skin", () => skinManager.CurrentSkinInfo.Value.ID != SkinInfo.DEFAULT_SKIN);
|
AddUntilStep("is modified default skin", () => skinManager.CurrentSkinInfo.Value.ID != SkinInfo.TRIANGLES_SKIN);
|
||||||
AddAssert("is not protected", () => skinManager.CurrentSkinInfo.Value.PerformRead(s => !s.Protected));
|
AddAssert("is not protected", () => skinManager.CurrentSkinInfo.Value.PerformRead(s => !s.Protected));
|
||||||
|
|
||||||
AddUntilStep("export button enabled", () => Game.Settings.ChildrenOfType<SkinSection.ExportSkinButton>().SingleOrDefault()?.Enabled.Value == true);
|
AddUntilStep("export button enabled", () => Game.Settings.ChildrenOfType<SkinSection.ExportSkinButton>().SingleOrDefault()?.Enabled.Value == true);
|
||||||
|
@ -34,6 +34,8 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
InputManager.MoveMouseTo(Vector2.Zero);
|
||||||
|
|
||||||
TimeToCompleteProgress = 2000;
|
TimeToCompleteProgress = 2000;
|
||||||
progressingNotifications.Clear();
|
progressingNotifications.Clear();
|
||||||
|
|
||||||
@ -230,6 +232,31 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddUntilStep("wait overlay not present", () => !notificationOverlay.IsPresent);
|
AddUntilStep("wait overlay not present", () => !notificationOverlay.IsPresent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestProgressClick()
|
||||||
|
{
|
||||||
|
ProgressNotification notification = null!;
|
||||||
|
|
||||||
|
AddStep("add progress notification", () =>
|
||||||
|
{
|
||||||
|
notification = new ProgressNotification
|
||||||
|
{
|
||||||
|
Text = @"Uploading to BSS...",
|
||||||
|
CompletionText = "Uploaded to BSS!",
|
||||||
|
};
|
||||||
|
notificationOverlay.Post(notification);
|
||||||
|
progressingNotifications.Add(notification);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("hover over notification", () => InputManager.MoveMouseTo(notificationOverlay.ChildrenOfType<ProgressNotification>().Single()));
|
||||||
|
|
||||||
|
AddStep("left click", () => InputManager.Click(MouseButton.Left));
|
||||||
|
AddAssert("not cancelled", () => notification.State == ProgressNotificationState.Active);
|
||||||
|
|
||||||
|
AddStep("right click", () => InputManager.Click(MouseButton.Right));
|
||||||
|
AddAssert("cancelled", () => notification.State == ProgressNotificationState.Cancelled);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestCompleteProgress()
|
public void TestCompleteProgress()
|
||||||
{
|
{
|
||||||
@ -301,7 +328,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
SimpleNotification notification = null!;
|
SimpleNotification notification = null!;
|
||||||
AddStep(@"post", () => notificationOverlay.Post(notification = new BackgroundNotification { Text = @"Welcome to osu!. Enjoy your stay!" }));
|
AddStep(@"post", () => notificationOverlay.Post(notification = new BackgroundNotification { Text = @"Welcome to osu!. Enjoy your stay!" }));
|
||||||
AddUntilStep("check is toast", () => !notification.IsInToastTray);
|
AddUntilStep("check is toast", () => notification.IsInToastTray);
|
||||||
AddAssert("light is not visible", () => notification.ChildrenOfType<Notification.NotificationLight>().Single().Alpha == 0);
|
AddAssert("light is not visible", () => notification.ChildrenOfType<Notification.NotificationLight>().Single().Alpha == 0);
|
||||||
|
|
||||||
AddUntilStep("wait for forward to overlay", () => !notification.IsInToastTray);
|
AddUntilStep("wait for forward to overlay", () => !notification.IsInToastTray);
|
||||||
|
@ -79,7 +79,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
switch (section)
|
switch (section)
|
||||||
{
|
{
|
||||||
case Section.Colours:
|
case Section.Colours:
|
||||||
HandleColours(output, line);
|
HandleColours(output, line, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void HandleColours<TModel>(TModel output, string line)
|
protected void HandleColours<TModel>(TModel output, string line, bool allowAlpha)
|
||||||
{
|
{
|
||||||
var pair = SplitKeyVal(line);
|
var pair = SplitKeyVal(line);
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte alpha = split.Length == 4 ? byte.Parse(split[3]) : (byte)255;
|
byte alpha = allowAlpha && split.Length == 4 ? byte.Parse(split[3]) : (byte)255;
|
||||||
colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), alpha);
|
colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), alpha);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -39,7 +39,7 @@ namespace osu.Game.Configuration
|
|||||||
{
|
{
|
||||||
// UI/selection defaults
|
// UI/selection defaults
|
||||||
SetDefault(OsuSetting.Ruleset, string.Empty);
|
SetDefault(OsuSetting.Ruleset, string.Empty);
|
||||||
SetDefault(OsuSetting.Skin, SkinInfo.DEFAULT_SKIN.ToString());
|
SetDefault(OsuSetting.Skin, SkinInfo.TRIANGLES_SKIN.ToString());
|
||||||
|
|
||||||
SetDefault(OsuSetting.BeatmapDetailTab, PlayBeatmapDetailArea.TabType.Details);
|
SetDefault(OsuSetting.BeatmapDetailTab, PlayBeatmapDetailArea.TabType.Details);
|
||||||
SetDefault(OsuSetting.BeatmapDetailModsFilter, false);
|
SetDefault(OsuSetting.BeatmapDetailModsFilter, false);
|
||||||
|
@ -69,8 +69,9 @@ namespace osu.Game.Database
|
|||||||
/// 22 2022-07-31 Added ModPreset.
|
/// 22 2022-07-31 Added ModPreset.
|
||||||
/// 23 2022-08-01 Added LastLocalUpdate to BeatmapInfo.
|
/// 23 2022-08-01 Added LastLocalUpdate to BeatmapInfo.
|
||||||
/// 24 2022-08-22 Added MaximumStatistics to ScoreInfo.
|
/// 24 2022-08-22 Added MaximumStatistics to ScoreInfo.
|
||||||
|
/// 25 2022-09-18 Remove skins to add with new naming.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const int schema_version = 24;
|
private const int schema_version = 25;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking realm retrieval during blocking periods.
|
/// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking realm retrieval during blocking periods.
|
||||||
@ -870,6 +871,11 @@ namespace osu.Game.Database
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 25:
|
||||||
|
// Remove the default skins so they can be added back by SkinManager with updated naming.
|
||||||
|
migration.NewRealm.RemoveRange(migration.NewRealm.All<SkinInfo>().Where(s => s.Protected));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,8 +229,8 @@ namespace osu.Game.Overlays.Notifications
|
|||||||
protected override bool OnClick(ClickEvent e)
|
protected override bool OnClick(ClickEvent e)
|
||||||
{
|
{
|
||||||
// Clicking with anything but left button should dismiss but not perform the activation action.
|
// Clicking with anything but left button should dismiss but not perform the activation action.
|
||||||
if (e.Button == MouseButton.Left)
|
if (e.Button == MouseButton.Left && Activated?.Invoke() == false)
|
||||||
Activated?.Invoke();
|
return true;
|
||||||
|
|
||||||
Close(false);
|
Close(false);
|
||||||
return true;
|
return true;
|
||||||
|
@ -78,8 +78,7 @@ namespace osu.Game.Overlays.Settings.Sections
|
|||||||
|
|
||||||
realmSubscription = realm.RegisterForNotifications(_ => realm.Realm.All<SkinInfo>()
|
realmSubscription = realm.RegisterForNotifications(_ => realm.Realm.All<SkinInfo>()
|
||||||
.Where(s => !s.DeletePending)
|
.Where(s => !s.DeletePending)
|
||||||
.OrderByDescending(s => s.Protected) // protected skins should be at the top.
|
.OrderBy(s => s.Name, StringComparer.OrdinalIgnoreCase), skinsChanged);
|
||||||
.ThenBy(s => s.Name, StringComparer.OrdinalIgnoreCase), skinsChanged);
|
|
||||||
|
|
||||||
skinDropdown.Current.BindValueChanged(skin =>
|
skinDropdown.Current.BindValueChanged(skin =>
|
||||||
{
|
{
|
||||||
@ -101,14 +100,17 @@ namespace osu.Game.Overlays.Settings.Sections
|
|||||||
if (!sender.Any())
|
if (!sender.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int protectedCount = sender.Count(s => s.Protected);
|
|
||||||
|
|
||||||
// For simplicity repopulate the full list.
|
// For simplicity repopulate the full list.
|
||||||
// In the future we should change this to properly handle ChangeSet events.
|
// In the future we should change this to properly handle ChangeSet events.
|
||||||
dropdownItems.Clear();
|
dropdownItems.Clear();
|
||||||
foreach (var skin in sender)
|
|
||||||
|
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.TRIANGLES_SKIN).ToLive(realm));
|
||||||
|
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.CLASSIC_SKIN).ToLive(realm));
|
||||||
|
|
||||||
|
dropdownItems.Add(random_skin_info);
|
||||||
|
|
||||||
|
foreach (var skin in sender.Where(s => !s.Protected))
|
||||||
dropdownItems.Add(skin.ToLive(realm));
|
dropdownItems.Add(skin.ToLive(realm));
|
||||||
dropdownItems.Insert(protectedCount, random_skin_info);
|
|
||||||
|
|
||||||
Schedule(() => skinDropdown.Items = dropdownItems);
|
Schedule(() => skinDropdown.Items = dropdownItems);
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
|
|
||||||
case BackgroundSource.Skin:
|
case BackgroundSource.Skin:
|
||||||
// default skins should use the default background rotation, which won't be the case if a SkinBackground is created for them.
|
// default skins should use the default background rotation, which won't be the case if a SkinBackground is created for them.
|
||||||
if (skin.Value is DefaultSkin || skin.Value is DefaultLegacySkin)
|
if (skin.Value is TrianglesSkin || skin.Value is DefaultLegacySkin)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
newBackground = new SkinBackground(skin.Value, getBackgroundTextureName());
|
newBackground = new SkinBackground(skin.Value, getBackgroundTextureName());
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Skinning
|
|||||||
public static SkinInfo CreateInfo() => new SkinInfo
|
public static SkinInfo CreateInfo() => new SkinInfo
|
||||||
{
|
{
|
||||||
ID = Skinning.SkinInfo.CLASSIC_SKIN, // this is temporary until database storage is decided upon.
|
ID = Skinning.SkinInfo.CLASSIC_SKIN, // this is temporary until database storage is decided upon.
|
||||||
Name = "osu!classic",
|
Name = "osu! \"classic\" (2013)",
|
||||||
Creator = "team osu!",
|
Creator = "team osu!",
|
||||||
Protected = true,
|
Protected = true,
|
||||||
InstantiationInfo = typeof(DefaultLegacySkin).GetInvariantInstantiationInfo()
|
InstantiationInfo = typeof(DefaultLegacySkin).GetInvariantInstantiationInfo()
|
||||||
|
@ -121,7 +121,7 @@ namespace osu.Game.Skinning
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case string when pair.Key.StartsWith("Colour", StringComparison.Ordinal):
|
case string when pair.Key.StartsWith("Colour", StringComparison.Ordinal):
|
||||||
HandleColours(currentConfig, line);
|
HandleColours(currentConfig, line, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Custom sprite paths
|
// Custom sprite paths
|
||||||
|
@ -48,7 +48,7 @@ namespace osu.Game.Skinning
|
|||||||
// osu!catch section only has colour settings
|
// osu!catch section only has colour settings
|
||||||
// so no harm in handling the entire section
|
// so no harm in handling the entire section
|
||||||
case Section.CatchTheBeat:
|
case Section.CatchTheBeat:
|
||||||
HandleColours(skin, line);
|
HandleColours(skin, line, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ namespace osu.Game.Skinning
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastDefaultSkinIndex = sources.IndexOf(sources.OfType<DefaultSkin>().LastOrDefault());
|
int lastDefaultSkinIndex = sources.IndexOf(sources.OfType<TrianglesSkin>().LastOrDefault());
|
||||||
|
|
||||||
// Ruleset resources should be given the ability to override game-wide defaults
|
// Ruleset resources should be given the ability to override game-wide defaults
|
||||||
// This is achieved by placing them before the last instance of DefaultSkin.
|
// This is achieved by placing them before the last instance of DefaultSkin.
|
||||||
|
@ -232,6 +232,9 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
skin.SkinInfo.PerformWrite(s =>
|
skin.SkinInfo.PerformWrite(s =>
|
||||||
{
|
{
|
||||||
|
// Update for safety
|
||||||
|
s.InstantiationInfo = skin.GetType().GetInvariantInstantiationInfo();
|
||||||
|
|
||||||
// Serialise out the SkinInfo itself.
|
// Serialise out the SkinInfo itself.
|
||||||
string skinInfoJson = JsonConvert.SerializeObject(s, new JsonSerializerSettings { Formatting = Formatting.Indented });
|
string skinInfoJson = JsonConvert.SerializeObject(s, new JsonSerializerSettings { Formatting = Formatting.Indented });
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Extensions.ObjectExtensions;
|
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
@ -19,7 +18,7 @@ namespace osu.Game.Skinning
|
|||||||
[JsonObject(MemberSerialization.OptIn)]
|
[JsonObject(MemberSerialization.OptIn)]
|
||||||
public class SkinInfo : RealmObject, IHasRealmFiles, IEquatable<SkinInfo>, IHasGuidPrimaryKey, ISoftDelete, IHasNamedFiles
|
public class SkinInfo : RealmObject, IHasRealmFiles, IEquatable<SkinInfo>, IHasGuidPrimaryKey, ISoftDelete, IHasNamedFiles
|
||||||
{
|
{
|
||||||
internal static readonly Guid DEFAULT_SKIN = new Guid("2991CFD8-2140-469A-BCB9-2EC23FBCE4AD");
|
internal static readonly Guid TRIANGLES_SKIN = new Guid("2991CFD8-2140-469A-BCB9-2EC23FBCE4AD");
|
||||||
internal static readonly Guid CLASSIC_SKIN = new Guid("81F02CD3-EEC6-4865-AC23-FAE26A386187");
|
internal static readonly Guid CLASSIC_SKIN = new Guid("81F02CD3-EEC6-4865-AC23-FAE26A386187");
|
||||||
internal static readonly Guid RANDOM_SKIN = new Guid("D39DFEFB-477C-4372-B1EA-2BCEA5FB8908");
|
internal static readonly Guid RANDOM_SKIN = new Guid("D39DFEFB-477C-4372-B1EA-2BCEA5FB8908");
|
||||||
|
|
||||||
@ -45,7 +44,16 @@ namespace osu.Game.Skinning
|
|||||||
var type = string.IsNullOrEmpty(InstantiationInfo)
|
var type = string.IsNullOrEmpty(InstantiationInfo)
|
||||||
// handle the case of skins imported before InstantiationInfo was added.
|
// handle the case of skins imported before InstantiationInfo was added.
|
||||||
? typeof(LegacySkin)
|
? typeof(LegacySkin)
|
||||||
: Type.GetType(InstantiationInfo).AsNonNull();
|
: Type.GetType(InstantiationInfo);
|
||||||
|
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
// Since the class was renamed from "DefaultSkin" to "TrianglesSkin", the type retrieval would fail
|
||||||
|
// for user modified skins. This aims to amicably handle that.
|
||||||
|
// If we ever add more default skins in the future this will need some kind of proper migration rather than
|
||||||
|
// a single fallback.
|
||||||
|
return new TrianglesSkin(this, resources);
|
||||||
|
}
|
||||||
|
|
||||||
return (Skin)Activator.CreateInstance(type, this, resources);
|
return (Skin)Activator.CreateInstance(type, this, resources);
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,9 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public readonly Bindable<Skin> CurrentSkin = new Bindable<Skin>();
|
public readonly Bindable<Skin> CurrentSkin = new Bindable<Skin>();
|
||||||
|
|
||||||
public readonly Bindable<Live<SkinInfo>> CurrentSkinInfo = new Bindable<Live<SkinInfo>>(Skinning.DefaultSkin.CreateInfo().ToLiveUnmanaged())
|
public readonly Bindable<Live<SkinInfo>> CurrentSkinInfo = new Bindable<Live<SkinInfo>>(TrianglesSkin.CreateInfo().ToLiveUnmanaged())
|
||||||
{
|
{
|
||||||
Default = Skinning.DefaultSkin.CreateInfo().ToLiveUnmanaged()
|
Default = TrianglesSkin.CreateInfo().ToLiveUnmanaged()
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly SkinImporter skinImporter;
|
private readonly SkinImporter skinImporter;
|
||||||
@ -59,14 +59,14 @@ namespace osu.Game.Skinning
|
|||||||
private readonly IResourceStore<byte[]> userFiles;
|
private readonly IResourceStore<byte[]> userFiles;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default skin.
|
/// The default "triangles" skin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Skin DefaultSkin { get; }
|
public Skin DefaultSkinTriangles { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default legacy skin.
|
/// The default "classic" skin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Skin DefaultLegacySkin { get; }
|
public Skin DefaultClassicSkin { get; }
|
||||||
|
|
||||||
public SkinManager(Storage storage, RealmAccess realm, GameHost host, IResourceStore<byte[]> resources, AudioManager audio, Scheduler scheduler)
|
public SkinManager(Storage storage, RealmAccess realm, GameHost host, IResourceStore<byte[]> resources, AudioManager audio, Scheduler scheduler)
|
||||||
: base(storage, realm)
|
: base(storage, realm)
|
||||||
@ -85,8 +85,8 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
var defaultSkins = new[]
|
var defaultSkins = new[]
|
||||||
{
|
{
|
||||||
DefaultLegacySkin = new DefaultLegacySkin(this),
|
DefaultClassicSkin = new DefaultLegacySkin(this),
|
||||||
DefaultSkin = new DefaultSkin(this),
|
DefaultSkinTriangles = new TrianglesSkin(this),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure the default entries are present.
|
// Ensure the default entries are present.
|
||||||
@ -104,7 +104,7 @@ namespace osu.Game.Skinning
|
|||||||
CurrentSkin.Value = skin.NewValue.PerformRead(GetSkin);
|
CurrentSkin.Value = skin.NewValue.PerformRead(GetSkin);
|
||||||
};
|
};
|
||||||
|
|
||||||
CurrentSkin.Value = DefaultSkin;
|
CurrentSkin.Value = DefaultSkinTriangles;
|
||||||
CurrentSkin.ValueChanged += skin =>
|
CurrentSkin.ValueChanged += skin =>
|
||||||
{
|
{
|
||||||
if (!skin.NewValue.SkinInfo.Equals(CurrentSkinInfo.Value))
|
if (!skin.NewValue.SkinInfo.Equals(CurrentSkinInfo.Value))
|
||||||
@ -125,7 +125,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
if (randomChoices.Length == 0)
|
if (randomChoices.Length == 0)
|
||||||
{
|
{
|
||||||
CurrentSkinInfo.Value = Skinning.DefaultSkin.CreateInfo().ToLiveUnmanaged();
|
CurrentSkinInfo.Value = TrianglesSkin.CreateInfo().ToLiveUnmanaged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,11 +229,11 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
yield return CurrentSkin.Value;
|
yield return CurrentSkin.Value;
|
||||||
|
|
||||||
if (CurrentSkin.Value is LegacySkin && CurrentSkin.Value != DefaultLegacySkin)
|
if (CurrentSkin.Value is LegacySkin && CurrentSkin.Value != DefaultClassicSkin)
|
||||||
yield return DefaultLegacySkin;
|
yield return DefaultClassicSkin;
|
||||||
|
|
||||||
if (CurrentSkin.Value != DefaultSkin)
|
if (CurrentSkin.Value != DefaultSkinTriangles)
|
||||||
yield return DefaultSkin;
|
yield return DefaultSkinTriangles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ namespace osu.Game.Skinning
|
|||||||
Guid currentUserSkin = CurrentSkinInfo.Value.ID;
|
Guid currentUserSkin = CurrentSkinInfo.Value.ID;
|
||||||
|
|
||||||
if (items.Any(s => s.ID == currentUserSkin))
|
if (items.Any(s => s.ID == currentUserSkin))
|
||||||
scheduler.Add(() => CurrentSkinInfo.Value = Skinning.DefaultSkin.CreateInfo().ToLiveUnmanaged());
|
scheduler.Add(() => CurrentSkinInfo.Value = TrianglesSkin.CreateInfo().ToLiveUnmanaged());
|
||||||
|
|
||||||
Delete(items.ToList(), silent);
|
Delete(items.ToList(), silent);
|
||||||
});
|
});
|
||||||
@ -310,10 +310,10 @@ namespace osu.Game.Skinning
|
|||||||
if (skinInfo == null)
|
if (skinInfo == null)
|
||||||
{
|
{
|
||||||
if (guid == SkinInfo.CLASSIC_SKIN)
|
if (guid == SkinInfo.CLASSIC_SKIN)
|
||||||
skinInfo = DefaultLegacySkin.SkinInfo;
|
skinInfo = DefaultClassicSkin.SkinInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentSkinInfo.Value = skinInfo ?? DefaultSkin.SkinInfo;
|
CurrentSkinInfo.Value = skinInfo ?? DefaultSkinTriangles.SkinInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
// Temporarily used to exclude undesirable ISkin implementations
|
// Temporarily used to exclude undesirable ISkin implementations
|
||||||
static bool isUserSkin(ISkin skin)
|
static bool isUserSkin(ISkin skin)
|
||||||
=> skin.GetType() == typeof(DefaultSkin)
|
=> skin.GetType() == typeof(TrianglesSkin)
|
||||||
|| skin.GetType() == typeof(DefaultLegacySkin)
|
|| skin.GetType() == typeof(DefaultLegacySkin)
|
||||||
|| skin.GetType() == typeof(LegacySkin);
|
|| skin.GetType() == typeof(LegacySkin);
|
||||||
}
|
}
|
||||||
|
@ -22,26 +22,26 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
public class DefaultSkin : Skin
|
public class TrianglesSkin : Skin
|
||||||
{
|
{
|
||||||
public static SkinInfo CreateInfo() => new SkinInfo
|
public static SkinInfo CreateInfo() => new SkinInfo
|
||||||
{
|
{
|
||||||
ID = osu.Game.Skinning.SkinInfo.DEFAULT_SKIN,
|
ID = osu.Game.Skinning.SkinInfo.TRIANGLES_SKIN,
|
||||||
Name = "osu! (triangles)",
|
Name = "osu! \"triangles\" (2017)",
|
||||||
Creator = "team osu!",
|
Creator = "team osu!",
|
||||||
Protected = true,
|
Protected = true,
|
||||||
InstantiationInfo = typeof(DefaultSkin).GetInvariantInstantiationInfo()
|
InstantiationInfo = typeof(TrianglesSkin).GetInvariantInstantiationInfo()
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly IStorageResourceProvider resources;
|
private readonly IStorageResourceProvider resources;
|
||||||
|
|
||||||
public DefaultSkin(IStorageResourceProvider resources)
|
public TrianglesSkin(IStorageResourceProvider resources)
|
||||||
: this(CreateInfo(), resources)
|
: this(CreateInfo(), resources)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)]
|
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)]
|
||||||
public DefaultSkin(SkinInfo skin, IStorageResourceProvider resources)
|
public TrianglesSkin(SkinInfo skin, IStorageResourceProvider resources)
|
||||||
: base(skin, resources)
|
: base(skin, resources)
|
||||||
{
|
{
|
||||||
this.resources = resources;
|
this.resources = resources;
|
@ -29,8 +29,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
public abstract class SkinnableTestScene : OsuGridTestScene, IStorageResourceProvider
|
public abstract class SkinnableTestScene : OsuGridTestScene, IStorageResourceProvider
|
||||||
{
|
{
|
||||||
|
private TrianglesSkin trianglesSkin;
|
||||||
private Skin metricsSkin;
|
private Skin metricsSkin;
|
||||||
private Skin defaultSkin;
|
private Skin legacySkin;
|
||||||
private Skin specialSkin;
|
private Skin specialSkin;
|
||||||
private Skin oldSkin;
|
private Skin oldSkin;
|
||||||
|
|
||||||
@ -47,8 +48,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
var dllStore = new DllResourceStore(GetType().Assembly);
|
var dllStore = new DllResourceStore(GetType().Assembly);
|
||||||
|
|
||||||
|
trianglesSkin = new TrianglesSkin(this);
|
||||||
metricsSkin = new TestLegacySkin(new SkinInfo { Name = "metrics-skin" }, new NamespacedResourceStore<byte[]>(dllStore, "Resources/metrics_skin"), this, true);
|
metricsSkin = new TestLegacySkin(new SkinInfo { Name = "metrics-skin" }, new NamespacedResourceStore<byte[]>(dllStore, "Resources/metrics_skin"), this, true);
|
||||||
defaultSkin = new DefaultLegacySkin(this);
|
legacySkin = new DefaultLegacySkin(this);
|
||||||
specialSkin = new TestLegacySkin(new SkinInfo { Name = "special-skin" }, new NamespacedResourceStore<byte[]>(dllStore, "Resources/special_skin"), this, true);
|
specialSkin = new TestLegacySkin(new SkinInfo { Name = "special-skin" }, new NamespacedResourceStore<byte[]>(dllStore, "Resources/special_skin"), this, true);
|
||||||
oldSkin = new TestLegacySkin(new SkinInfo { Name = "old-skin" }, new NamespacedResourceStore<byte[]>(dllStore, "Resources/old_skin"), this, true);
|
oldSkin = new TestLegacySkin(new SkinInfo { Name = "old-skin" }, new NamespacedResourceStore<byte[]>(dllStore, "Resources/old_skin"), this, true);
|
||||||
}
|
}
|
||||||
@ -61,9 +63,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
var beatmap = CreateBeatmapForSkinProvider();
|
var beatmap = CreateBeatmapForSkinProvider();
|
||||||
|
|
||||||
Cell(0).Child = createProvider(null, creationFunction, beatmap);
|
Cell(0).Child = createProvider(trianglesSkin, creationFunction, beatmap);
|
||||||
Cell(1).Child = createProvider(metricsSkin, creationFunction, beatmap);
|
Cell(1).Child = createProvider(metricsSkin, creationFunction, beatmap);
|
||||||
Cell(2).Child = createProvider(defaultSkin, creationFunction, beatmap);
|
Cell(2).Child = createProvider(legacySkin, creationFunction, beatmap);
|
||||||
Cell(3).Child = createProvider(specialSkin, creationFunction, beatmap);
|
Cell(3).Child = createProvider(specialSkin, creationFunction, beatmap);
|
||||||
Cell(4).Child = createProvider(oldSkin, creationFunction, beatmap);
|
Cell(4).Child = createProvider(oldSkin, creationFunction, beatmap);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user