This commit is contained in:
LA
2025-03-16 00:42:56 +08:00
parent 4e78a8a235
commit e9ca51bd1d
41 changed files with 887 additions and 159 deletions

0
.globalconfig Normal file
View File

View File

@@ -1,29 +1,31 @@
{
"solution": {
"path": "osu.sln",
"projects": [
"osu.Desktop\\osu.Desktop.csproj",
"osu.Game.Benchmarks\\osu.Game.Benchmarks.csproj",
"osu.Game.Rulesets.Catch.Tests\\osu.Game.Rulesets.Catch.Tests.csproj",
"osu.Game.Rulesets.Catch\\osu.Game.Rulesets.Catch.csproj",
"osu.Game.Rulesets.Mania.Tests\\osu.Game.Rulesets.Mania.Tests.csproj",
"osu.Game.Rulesets.Mania\\osu.Game.Rulesets.Mania.csproj",
"osu.Game.Rulesets.Osu.Tests\\osu.Game.Rulesets.Osu.Tests.csproj",
"osu.Game.Rulesets.Osu\\osu.Game.Rulesets.Osu.csproj",
"osu.Game.Rulesets.Taiko.Tests\\osu.Game.Rulesets.Taiko.Tests.csproj",
"osu.Game.Rulesets.Taiko\\osu.Game.Rulesets.Taiko.csproj",
"osu.Game.Tests\\osu.Game.Tests.csproj",
"osu.Game.Tournament.Tests\\osu.Game.Tournament.Tests.csproj",
"osu.Game.Tournament\\osu.Game.Tournament.csproj",
"osu.Game\\osu.Game.csproj",
"Templates\\Rulesets\\ruleset-empty\\osu.Game.Rulesets.EmptyFreeform.Tests\\osu.Game.Rulesets.EmptyFreeform.Tests.csproj",
"Templates\\Rulesets\\ruleset-empty\\osu.Game.Rulesets.EmptyFreeform\\osu.Game.Rulesets.EmptyFreeform.csproj",
"Templates\\Rulesets\\ruleset-example\\osu.Game.Rulesets.Pippidon.Tests\\osu.Game.Rulesets.Pippidon.Tests.csproj",
"Templates\\Rulesets\\ruleset-example\\osu.Game.Rulesets.Pippidon\\osu.Game.Rulesets.Pippidon.csproj",
"Templates\\Rulesets\\ruleset-scrolling-empty\\osu.Game.Rulesets.EmptyScrolling.Tests\\osu.Game.Rulesets.EmptyScrolling.Tests.csproj",
"Templates\\Rulesets\\ruleset-scrolling-empty\\osu.Game.Rulesets.EmptyScrolling\\osu.Game.Rulesets.EmptyScrolling.csproj",
"Templates\\Rulesets\\ruleset-scrolling-example\\osu.Game.Rulesets.Pippidon.Tests\\osu.Game.Rulesets.Pippidon.Tests.csproj",
"Templates\\Rulesets\\ruleset-scrolling-example\\osu.Game.Rulesets.Pippidon\\osu.Game.Rulesets.Pippidon.csproj"
]
}
}
{
"solution": {
"path": "osu.sln",
"projects": [
"..\\osu-resources\\osu.Game.Resources\\osu.Game.Resources.csproj",
"osu.Desktop\\osu.Desktop.csproj",
"osu.Game.Benchmarks\\osu.Game.Benchmarks.csproj",
"osu.Game.Rulesets.Catch.Tests\\osu.Game.Rulesets.Catch.Tests.csproj",
"osu.Game.Rulesets.Catch\\osu.Game.Rulesets.Catch.csproj",
"osu.Game.Rulesets.Mania.Tests\\osu.Game.Rulesets.Mania.Tests.csproj",
"osu.Game.Rulesets.Mania\\osu.Game.Rulesets.Mania.csproj",
"osu.Game.Rulesets.Osu.Tests\\osu.Game.Rulesets.Osu.Tests.csproj",
"osu.Game.Rulesets.Osu\\osu.Game.Rulesets.Osu.csproj",
"osu.Game.Rulesets.Taiko.Tests\\osu.Game.Rulesets.Taiko.Tests.csproj",
"osu.Game.Rulesets.Taiko\\osu.Game.Rulesets.Taiko.csproj",
"osu.Game.Tests\\osu.Game.Tests.csproj",
"osu.Game.Tournament.Tests\\osu.Game.Tournament.Tests.csproj",
"osu.Game.Tournament\\osu.Game.Tournament.csproj",
"osu.Game\\osu.Game.csproj",
"Templates\\Rulesets\\ruleset-empty\\osu.Game.Rulesets.EmptyFreeform.Tests\\osu.Game.Rulesets.EmptyFreeform.Tests.csproj",
"Templates\\Rulesets\\ruleset-empty\\osu.Game.Rulesets.EmptyFreeform\\osu.Game.Rulesets.EmptyFreeform.csproj",
"Templates\\Rulesets\\ruleset-example\\osu.Game.Rulesets.Pippidon.Tests\\osu.Game.Rulesets.Pippidon.Tests.csproj",
"Templates\\Rulesets\\ruleset-example\\osu.Game.Rulesets.Pippidon\\osu.Game.Rulesets.Pippidon.csproj",
"Templates\\Rulesets\\ruleset-scrolling-empty\\osu.Game.Rulesets.EmptyScrolling.Tests\\osu.Game.Rulesets.EmptyScrolling.Tests.csproj",
"Templates\\Rulesets\\ruleset-scrolling-empty\\osu.Game.Rulesets.EmptyScrolling\\osu.Game.Rulesets.EmptyScrolling.csproj",
"Templates\\Rulesets\\ruleset-scrolling-example\\osu.Game.Rulesets.Pippidon.Tests\\osu.Game.Rulesets.Pippidon.Tests.csproj",
"Templates\\Rulesets\\ruleset-scrolling-example\\osu.Game.Rulesets.Pippidon\\osu.Game.Rulesets.Pippidon.csproj",
"../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj"
]
}
}

View File

@@ -21,13 +21,16 @@ namespace osu.Desktop
public static class Program
{
#if DEBUG
private const string base_game_name = @"osu-development";
private const string base_game_name = @"osu-Ez2Lazer-development";
#else
private const string base_game_name = @"osu";
private const string base_game_name = @"osu-Ez2Lazer";
#endif
private static LegacyTcpIpcProvider? legacyIpc;
// [DllImport("kernel32.dll", SetLastError = true)]
// private static extern bool SetDllDirectory(string lpPathName);
[STAThread]
public static void Main(string[] args)
{
@@ -58,6 +61,8 @@ namespace osu.Desktop
return;
}
}
// SetDllDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "C:\\Users\\12456\\.nuget\\packages\\bass.asio\\1.3.1.2\\build\\native\\x64"));
}
// NVIDIA profiles are based on the executable name of a process.

View File

@@ -23,11 +23,16 @@ using osu.Game.Rulesets.Mania.Difficulty;
using osu.Game.Rulesets.Mania.Edit;
using osu.Game.Rulesets.Mania.Edit.Setup;
using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mania.Mods.LAsMods;
using osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Skinning.Ez2;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mania.Skinning.Argon;
using osu.Game.Rulesets.Mania.Skinning.Default;
using osu.Game.Rulesets.Mania.Skinning.Legacy;
using osu.Game.Rulesets.Mania.Skinning.SbI;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Replays.Types;
@@ -46,7 +51,7 @@ namespace osu.Game.Rulesets.Mania
/// <summary>
/// The maximum number of supported keys in a single stage.
/// </summary>
public const int MAX_STAGE_KEYS = 10;
public const int MAX_STAGE_KEYS = 18;
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod>? mods = null) => new DrawableManiaRuleset(this, beatmap, mods);
@@ -76,6 +81,12 @@ namespace osu.Game.Rulesets.Mania
case ArgonSkin:
return new ManiaArgonSkinTransformer(skin, beatmap);
case Ez2Skin:
return new ManiaEz2SkinTransformer(skin, beatmap);
case SbISkin:
return new ManiaSbISkinTransformer(skin, beatmap);
case DefaultLegacySkin:
return new ManiaClassicSkinTransformer(skin, beatmap);
@@ -265,18 +276,18 @@ namespace osu.Game.Rulesets.Mania
new ManiaModInvert(),
new ManiaModConstantSpeed(),
new ManiaModHoldOff(),
new MultiMod(
new ManiaModKey1(),
new ManiaModKey2(),
new ManiaModKey3(),
new ManiaModKey4(),
new ManiaModKey5(),
new ManiaModKey6(),
new ManiaModKey7(),
new ManiaModKey8(),
new ManiaModKey9(),
new ManiaModKey10()
),
// new MultiMod(
// new ManiaModKey1(),
// new ManiaModKey2(),
// new ManiaModKey3(),
// new ManiaModKey4(),
// new ManiaModKey5(),
// new ManiaModKey6(),
// new ManiaModKey7(),
// new ManiaModKey8(),
// new ManiaModKey9(),
// new ManiaModKey10()
// ),
};
case ModType.Automation:
@@ -285,6 +296,34 @@ namespace osu.Game.Rulesets.Mania
new MultiMod(new ManiaModAutoplay(), new ManiaModCinema()),
};
case ModType.CustomMod:
return new Mod[]
{
new ManiaModEz2Settings(),
new ManiaModCustomHit(),
new ManiaModNiceBPM(),
new ManiaModSpaceBody(),
// new ManiaModAdjust(),
new StarRatingRebirth(),
new ManiaModNtoMAnother(),
new ManiaModNtoM(),
new ManiaModDuplicate(),
new ManiaModDoublePlay(),
new ManiaModNoteAdjust(),
new ManiaModLNTransformer(),
new ManiaModLNLongShortAddition(),
new ManiaModLNDoubleDistribution(),
new ManiaModLNSimplify(),
new ManiaModJackAdjust(),
new ManiaModDeleteSpace(),
new ManiaModCleaner(),
// new ManiaModNewJudgement(),
// new ManiaModJudgmentsAdjust(),
new ManiaModRemedy(),
new ManiaModGracer(),
new ManiaModReleaseAdjust(),
};
case ModType.Fun:
return new Mod[]
{
@@ -330,8 +369,8 @@ namespace osu.Game.Rulesets.Mania
{
for (int i = 1; i <= MAX_STAGE_KEYS; i++)
yield return (int)PlayfieldType.Single + i;
for (int i = 2; i <= MAX_STAGE_KEYS * 2; i += 2)
yield return (int)PlayfieldType.Dual + i;
// for (int i = 2; i <= MAX_STAGE_KEYS * 2; i += 2)
// yield return (int)PlayfieldType.Dual + i;
}
}
@@ -342,8 +381,8 @@ namespace osu.Game.Rulesets.Mania
case PlayfieldType.Single:
return new SingleStageVariantGenerator(variant).GenerateMappings();
case PlayfieldType.Dual:
return new DualStageVariantGenerator(getDualStageKeyCount(variant)).GenerateMappings();
// case PlayfieldType.Dual:
// return new DualStageVariantGenerator(getDualStageKeyCount(variant)).GenerateMappings();
}
return Array.Empty<KeyBinding>();
@@ -356,19 +395,19 @@ namespace osu.Game.Rulesets.Mania
default:
return $"{variant}K";
case PlayfieldType.Dual:
{
int keys = getDualStageKeyCount(variant);
return $"{keys}K + {keys}K";
}
// case PlayfieldType.Dual:
// {
// int keys = getDualStageKeyCount(variant);
// return $"{keys}K + {keys}K";
// }
}
}
/// <summary>
/// Finds the number of keys for each stage in a <see cref="PlayfieldType.Dual"/> variant.
/// </summary>
/// <param name="variant">The variant.</param>
private int getDualStageKeyCount(int variant) => (variant - (int)PlayfieldType.Dual) / 2;
// /// <summary>
// /// Finds the number of keys for each stage in a <see cref="PlayfieldType.Dual"/> variant.
// /// </summary>
// /// <param name="variant">The variant.</param>
// private int getDualStageKeyCount(int variant) => (variant - (int)PlayfieldType.Dual) / 2;
/// <summary>
/// Finds the <see cref="PlayfieldType"/> that corresponds to a variant value.
@@ -389,30 +428,82 @@ namespace osu.Game.Rulesets.Mania
HitResult.Good,
HitResult.Ok,
HitResult.Meh,
HitResult.IgnoreHit,
HitResult.IgnoreMiss,
// HitResult.SmallBonus is used for awarding perfect bonus score but is not included here as
// it would be a bit redundant to show this to the user.
};
}
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
// public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
// {
// new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
// {
// RelativeSizeAxes = Axes.X,
// AutoSizeAxes = Axes.Y
// }),
// new StatisticItem("Timing Distribution", () => new HitEventTimingDistributionGraph(score.HitEvents) //判定偏移
// {
// RelativeSizeAxes = Axes.X,
// Height = 200
// }, true),
// new StatisticItem("Statistics", () => new SimpleStatisticTable(2, new SimpleStatisticItem[]
// {
// new AverageHitError(score.HitEvents),
// new UnstableRate(score.HitEvents)
// }), true),
// };
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) //单轨道判定分布
{
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
var hitEventsByColumn = score.HitEvents
.Where(e => e.HitObject is ManiaHitObject)
.GroupBy(e => ((ManiaHitObject)e.HitObject).Column)
.OrderBy(g => g.Key)
.ToList();
var statistics = new List<StatisticItem>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}),
new StatisticItem("Timing Distribution", () => new HitEventTimingDistributionGraph(score.HitEvents)
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}),
new StatisticItem("Timing Distribution", () => new HitEventTimingDistributionGraph(score.HitEvents)
{
RelativeSizeAxes = Axes.X,
Height = 300
}, true),
new StatisticItem("Statistics", () => new SimpleStatisticTable(2, new SimpleStatisticItem[]
{
new AverageHitError(score.HitEvents),
new UnstableRate(score.HitEvents)
}), true)
};
foreach (var column in hitEventsByColumn)
{
RelativeSizeAxes = Axes.X,
Height = 250
}, true),
new StatisticItem("Statistics", () => new SimpleStatisticTable(2, new SimpleStatisticItem[]
{
new AverageHitError(score.HitEvents),
new UnstableRate(score.HitEvents)
}), true)
};
statistics.Add(new StatisticItem($"Timing Distribution - Column {column.Key + 1}", () => new HitEventTimingDistributionGraph(column.ToList())
{
RelativeSizeAxes = Axes.X,
Height = 80,
}, true));
}
return statistics.ToArray();
}
// public override DrawableCarouselBeatmap updateKeyCount()
// {
// base.UpdateKeyCount();
//
// // Assuming you have access to the beatmap instance
// if (calculator1S(beatmap))
// {
// keyCountText.Text = $"[{keyCount - 1}K1S]";
// }
// }
public override IRulesetFilterCriteria CreateRulesetFilterCriteria()
{

View File

@@ -19,14 +19,34 @@ namespace osu.Game.Rulesets.Mania
// 10K is special because it expands towards the centre of the keyboard (V/N), rather than towards the edges of the keyboard.
if (variant == 10)
{
leftKeys = new[] { InputKey.A, InputKey.S, InputKey.D, InputKey.F, InputKey.V };
rightKeys = new[] { InputKey.N, InputKey.J, InputKey.K, InputKey.L, InputKey.Semicolon };
leftKeys = new[] { InputKey.LControl, InputKey.A, InputKey.S, InputKey.D, InputKey.Space };
rightKeys = new[] { InputKey.Slash, InputKey.L, InputKey.Semicolon, InputKey.Quote, InputKey.Enter };
}
else
else if (variant == 12)
{
leftKeys = new[] { InputKey.A, InputKey.S, InputKey.D, InputKey.F };
rightKeys = new[] { InputKey.J, InputKey.K, InputKey.L, InputKey.Semicolon };
leftKeys = new[] { InputKey.Tab, InputKey.LControl, InputKey.A, InputKey.S, InputKey.D, InputKey.Space };
rightKeys = new[] { InputKey.Slash, InputKey.L, InputKey.Semicolon, InputKey.Quote, InputKey.Enter, InputKey.BackSlash };
}
else if (variant == 14)
{
leftKeys = new[] { InputKey.Tab, InputKey.LControl, InputKey.A, InputKey.S, InputKey.D, InputKey.Space, InputKey.G };
rightKeys = new[] { InputKey.Slash, InputKey.L, InputKey.Semicolon, InputKey.Quote, InputKey.Enter, InputKey.BackSlash, InputKey.P };
}
else if (variant == 16)
{
leftKeys = new[] { InputKey.Tab, InputKey.LControl, InputKey.A, InputKey.S, InputKey.D, InputKey.Space, InputKey.Number5, InputKey.Number6 };
rightKeys = new[] { InputKey.Number7, InputKey.Number8, InputKey.Slash, InputKey.L, InputKey.Semicolon, InputKey.Quote, InputKey.Enter, InputKey.BackSlash };
}
else // if (variant == 18)
{
leftKeys = new[] { InputKey.Q, InputKey.W, InputKey.E, InputKey.R, InputKey.A, InputKey.S, InputKey.D, InputKey.F, InputKey.Space };
rightKeys = new[] { InputKey.Alt, InputKey.L, InputKey.Semicolon, InputKey.Quote, InputKey.Enter, InputKey.O, InputKey.P, InputKey.BracketLeft, InputKey.BracketRight };
}
// else
// {
// leftKeys = new[] { InputKey.A, InputKey.S, InputKey.D, InputKey.F };
// rightKeys = new[] { InputKey.J, InputKey.K, InputKey.L, InputKey.Semicolon };
// }
}
public IEnumerable<KeyBinding> GenerateMappings() => new VariantMappingGenerator

View File

@@ -0,0 +1,89 @@
// 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.
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Localisation.SkinComponents;
using osu.Game.Resources.Localisation.Web;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play.HUD;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Skinning.Ez2.Ez2HUD
{
public partial class EzComComboText : ComboCounter
{
public EzComCounterText Text = null!;
protected override double RollingDuration => 250;
protected virtual bool DisplayXSymbol => true;
[SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.ShowLabel), nameof(SkinnableComponentStrings.ShowLabelDescription))]
public Bindable<bool> ShowLabel { get; } = new BindableBool(true);
[BackgroundDependencyLoader]
private void load(ScoreProcessor scoreProcessor)
{
Current.BindTo(scoreProcessor.Combo);
Current.BindValueChanged(combo =>
{
bool wasIncrease = combo.NewValue > combo.OldValue;
bool wasMiss = combo.OldValue > 1 && combo.NewValue == 0;
float newScale = Math.Clamp(Text.NumberContainer.Scale.X * (wasIncrease ? 1.1f : 0.8f), 0.6f, 1.4f);
float duration = wasMiss ? 1000 : 100;
Text.NumberContainer
.ScaleTo(new Vector2(newScale))
.ScaleTo(Vector2.One, duration, Easing.OutQuint);
if (wasMiss)
Text.FlashColour(Color4.Red, duration, Easing.OutQuint);
});
}
public override int DisplayedCount
{
get => base.DisplayedCount;
set
{
base.DisplayedCount = value;
updateWireframe();
}
}
private void updateWireframe()
{
int digitsRequiredForDisplayCount = getDigitsRequiredForDisplayCount();
if (digitsRequiredForDisplayCount != Text.WireframeTemplate.Length)
Text.WireframeTemplate = new string('#', digitsRequiredForDisplayCount);
}
private int getDigitsRequiredForDisplayCount()
{
// one for the single presumed starting digit, one for the "x" at the end (unless disabled).
int digitsRequired = DisplayXSymbol ? 2 : 1;
long c = DisplayedCount;
while ((c /= 10) > 0)
digitsRequired++;
return digitsRequired;
}
protected override LocalisableString FormatCount(int count) => DisplayXSymbol ? @"Combo" : count.ToString();
protected override IHasText CreateText() => Text = new EzComCounterText(Anchor.TopLeft, MatchesStrings.MatchScoreStatsCombo.ToUpper())
{
ShowLabel = { BindTarget = ShowLabel },
};
}
}

View File

@@ -101,8 +101,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.SbI
case ManiaSkinComponentLookup maniaComponent:
switch (maniaComponent.Component)
{
case ManiaSkinComponents.StageBackground:
return new SbIStageBackground();
// case ManiaSkinComponents.StageBackground:
// return new SbIStageBackground();
case ManiaSkinComponents.ColumnBackground:
// if (Skin is SbISkin && resultComponent.Component >= HitResult.Perfect)

View File

@@ -29,7 +29,11 @@ namespace osu.Game.Rulesets.Mania.UI
direction.BindValueChanged(_ => onDirectionChanged(), true);
}
private void onDirectionChanged() => Y = direction.Value == ScrollingDirection.Up ? -judgement_y_position : judgement_y_position;
private void onDirectionChanged()
{
Anchor = direction.Value == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
Y = direction.Value == ScrollingDirection.Up ? -judgement_y_position : judgement_y_position;
}
protected override void LoadComplete()
{

View File

@@ -484,7 +484,7 @@ namespace osu.Game.Rulesets.Osu.Tests
public override bool IsHitResultAllowed(HitResult result) => result == HitResult.Great || result == HitResult.Miss;
protected override DifficultyRange[] GetRanges() => ranges;
public override DifficultyRange[] GetRanges() => ranges;
}
private partial class ScoreAccessibleReplayPlayer : ReplayPlayer

View File

@@ -34,6 +34,6 @@ namespace osu.Game.Rulesets.Osu.Scoring
return false;
}
protected override DifficultyRange[] GetRanges() => OSU_RANGES;
public override DifficultyRange[] GetRanges() => OSU_RANGES;
}
}

View File

@@ -27,6 +27,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring
return false;
}
protected override DifficultyRange[] GetRanges() => TAIKO_RANGES;
public override DifficultyRange[] GetRanges() => TAIKO_RANGES;
}
}

View File

@@ -29,6 +29,8 @@ namespace osu.Game.Beatmaps
public readonly BeatmapInfo BeatmapInfo;
public readonly BeatmapSetInfo BeatmapSetInfo;
public IBeatmap BeatmapAfterConverted { get; set; }
// TODO: remove once the fallback lookup is not required (and access via `working.BeatmapInfo.Metadata` directly).
public BeatmapMetadata Metadata => BeatmapInfo.Metadata;
@@ -347,6 +349,7 @@ namespace osu.Game.Beatmaps
mod.ApplyToBeatmap(converted);
}
BeatmapAfterConverted = converted;
return converted;
}

View File

@@ -39,17 +39,18 @@ namespace osu.Game.Configuration
{
// UI/selection defaults
SetDefault(OsuSetting.Ruleset, string.Empty);
SetDefault(OsuSetting.Skin, SkinInfo.ARGON_SKIN.ToString());
SetDefault(OsuSetting.Skin, SkinInfo.EZ2_SKIN.ToString());
SetDefault(OsuSetting.BeatmapDetailTab, PlayBeatmapDetailArea.TabType.Local);
SetDefault(OsuSetting.BeatmapDetailModsFilter, false);
SetDefault(OsuSetting.ShowConvertedBeatmaps, true);
SetDefault(OsuSetting.ShowConvertedBeatmaps, false);
SetDefault(OsuSetting.DisplayStarsMinimum, 0.0, 0, 10, 0.1);
SetDefault(OsuSetting.DisplayStarsMaximum, 10.1, 0, 10.1, 0.1);
SetDefault(OsuSetting.SongSelectGroupingMode, GroupMode.All);
SetDefault(OsuSetting.SongSelectSortingMode, SortMode.Title);
SetDefault(OsuSetting.SelectEzMode, SelectEzMode.All);
SetDefault(OsuSetting.RandomSelectAlgorithm, RandomSelectAlgorithm.RandomPermutation);
SetDefault(OsuSetting.ModSelectHotkeyStyle, ModSelectHotkeyStyle.Sequential);
@@ -120,7 +121,7 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.TouchDisableGameplayTaps, false);
// Graphics
SetDefault(OsuSetting.ShowFpsDisplay, false);
SetDefault(OsuSetting.ShowFpsDisplay, true);
SetDefault(OsuSetting.ShowStoryboard, true);
SetDefault(OsuSetting.BeatmapSkins, true);
@@ -135,7 +136,7 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.Prefer24HourTime, !CultureInfoHelper.SystemCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt"));
// Gameplay
SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1, 0.01f);
SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.8f, 0, 1, 0.01f);
SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01);
SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01);
SetDefault(OsuSetting.LightenDuringBreaks, true);
@@ -146,7 +147,7 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Always);
SetDefault(OsuSetting.ShowHealthDisplayWhenCantFail, true);
SetDefault(OsuSetting.FadePlayfieldWhenHealthLow, true);
SetDefault(OsuSetting.KeyOverlay, false);
SetDefault(OsuSetting.KeyOverlay, true);
SetDefault(OsuSetting.ReplaySettingsOverlay, true);
SetDefault(OsuSetting.ReplayPlaybackControlsExpanded, true);
SetDefault(OsuSetting.GameplayLeaderboard, true);
@@ -155,6 +156,9 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.FloatingComments, false);
SetDefault(OsuSetting.ScoreDisplayMode, ScoringMode.Standardised);
SetDefault(OsuSetting.HitMode, HitWindows.HitMode.Standardised);
SetDefault(OsuSetting.AccuracyCutoffS, 0.9, 0.95, 1, 0.01);
SetDefault(OsuSetting.AccuracyCutoffA, 0.9, 0.9, 1, 0.01);
SetDefault(OsuSetting.IncreaseFirstObjectVisibility, true);
SetDefault(OsuSetting.GameplayDisableWinKey, true);
@@ -170,6 +174,8 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.ScreenshotFormat, ScreenshotFormat.Jpg);
SetDefault(OsuSetting.ScreenshotCaptureMenuCursor, false);
SetDefault(OsuSetting.SongSelectRightMouseScroll, true);
SetDefault(OsuSetting.Scaling, ScalingMode.Off);
SetDefault(OsuSetting.SafeAreaConsiderations, true);
SetDefault(OsuSetting.ScalingBackgroundDim, 0.9f, 0.5f, 1f, 0.01f);
@@ -217,8 +223,8 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.EditorContractSidebars, false);
SetDefault(OsuSetting.AlwaysShowHoldForMenuButton, false);
SetDefault(OsuSetting.AlwaysRequireHoldingForPause, false);
SetDefault(OsuSetting.AlwaysShowHoldForMenuButton, true);
SetDefault(OsuSetting.AlwaysRequireHoldingForPause, true);
SetDefault(OsuSetting.EditorShowStoryboard, true);
SetDefault(OsuSetting.EditorSubmissionNotifyOnDiscussionReplies, true);
@@ -405,11 +411,16 @@ namespace osu.Game.Configuration
Skin,
ScreenshotFormat,
ScreenshotCaptureMenuCursor,
SongSelectRightMouseScroll,
BeatmapSkins,
BeatmapColours,
BeatmapHitsounds,
IncreaseFirstObjectVisibility,
ScoreDisplayMode,
SelectEzMode,
HitMode,
AccuracyCutoffS,
AccuracyCutoffA,
ExternalLinkWarning,
PreferNoVideo,
Scaling,
@@ -451,7 +462,6 @@ namespace osu.Game.Configuration
/// The status for the current user to broadcast to other players.
/// </summary>
UserOnlineStatus,
MultiplayerRoomFilter,
HideCountryFlags,
EditorTimelineShowTimingChanges,

View File

@@ -154,6 +154,9 @@ namespace osu.Game.Graphics
{
switch (modType)
{
case ModType.CustomMod:
return BlueLight;
case ModType.Automation:
return Blue1;

View File

@@ -28,6 +28,8 @@ namespace osu.Game.Graphics
public static FontUsage Inter => GetFont(Typeface.Inter, weight: FontWeight.Regular);
public static FontUsage Stat => GetFont(Typeface.Stat, weight: FontWeight.Light);
/// <summary>
/// Retrieves a <see cref="FontUsage"/>.
/// </summary>
@@ -70,6 +72,9 @@ namespace osu.Game.Graphics
case Typeface.Inter:
return @"Inter";
case Typeface.Stat:
return @"Stat";
}
return null;
@@ -120,6 +125,7 @@ namespace osu.Game.Graphics
[Description("Torus (alternate)")]
TorusAlternate,
Inter,
Stat,
}
public enum FontWeight

View File

@@ -109,6 +109,21 @@ namespace osu.Game.Localisation
/// </summary>
public static LocalisableString ScoreDisplayMode => new TranslatableString(getKey(@"score_display_mode"), @"Score display mode");
/// <summary>
/// "Hit Mode(No Active)"
/// </summary>
public static LocalisableString HitMode => new TranslatableString(getKey(@"hit_mode"), @"Hit Mode(No Active)");
/// <summary>
/// "Accuracy Cutoff S"
/// </summary>
public static LocalisableString AccuracyCutoffS => new TranslatableString(getKey(@"accuracy_cutoff_s"), @"Accuracy Cutoff S");
/// <summary>
/// "Accuracy Cutoff A"
/// </summary>
public static LocalisableString AccuracyCutoffA => new TranslatableString(getKey(@"accuracy_cutoff_a"), @"Accuracy Cutoff A");
/// <summary>
/// "Disable Windows key during gameplay"
/// </summary>

View File

@@ -82,7 +82,7 @@ namespace osu.Game.Localisation
/// <summary>
/// "{0}ms (speed {1:N1})"
/// </summary>
public static LocalisableString ScrollSpeedTooltip(int scrollTime, double scrollSpeed) => new TranslatableString(getKey(@"ruleset"), @"{0}ms (speed {1:N1})", scrollTime, scrollSpeed);
public static LocalisableString ScrollSpeedTooltip(double scrollTime, double scrollSpeed) => new TranslatableString(getKey(@"ruleset"), @"{0}ms (speed {1:N1})", scrollTime, scrollSpeed);
/// <summary>
/// "Touch control scheme"
@@ -109,6 +109,21 @@ namespace osu.Game.Localisation
/// </summary>
public static LocalisableString LandscapeTouchOverlay => new TranslatableString(getKey(@"landscape_touch_overlay"), @"Landscape (touch overlay)");
/// <summary>
/// "Scrolling style"
/// </summary>
public static LocalisableString ScrollingStyle => new TranslatableString(getKey(@"scrolling_style"), @"Scrolling style");
/// <summary>
/// "Scroll Base MS (200 Speed)"
/// </summary>
public static LocalisableString ScrollBaseSpeed => new TranslatableString(getKey(@"scroll_base_speed"), @"Scroll Base MS (200 Speed)");
/// <summary>
/// "Scroll time precision"
/// </summary>
public static LocalisableString ScrollTimePrecision => new TranslatableString(getKey(@"scrolling_time_precision"), @"Scroll time precision");
private static string getKey(string key) => $@"{prefix}:{key}";
}
}

View File

@@ -324,6 +324,7 @@ namespace osu.Game.Overlays.Mods
});
}
yield return createModColumnContent(ModType.CustomMod);
yield return createModColumnContent(ModType.DifficultyReduction);
yield return createModColumnContent(ModType.DifficultyIncrease);
yield return createModColumnContent(ModType.Automation);

View File

@@ -26,6 +26,27 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
Current = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode),
Keywords = new[] { "scoring" }
},
new SettingsEnumDropdown<HitWindows.HitMode>
{
ClassicDefault = HitWindows.HitMode.Classic,
LabelText = GameplaySettingsStrings.HitMode,
Current = config.GetBindable<HitWindows.HitMode>(OsuSetting.HitMode),
Keywords = new[] { "scoring" }
},
new SettingsSlider<double>
{
LabelText = GameplaySettingsStrings.AccuracyCutoffS,
Current = config.GetBindable<double>(OsuSetting.AccuracyCutoffS),
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new SettingsSlider<double>
{
LabelText = GameplaySettingsStrings.AccuracyCutoffA,
Current = config.GetBindable<double>(OsuSetting.AccuracyCutoffA),
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new SettingsCheckbox
{
LabelText = GraphicsSettingsStrings.HitLighting,

View File

@@ -126,6 +126,8 @@ namespace osu.Game.Overlays.Settings.Sections
// In the future we should change this to properly handle ChangeSet events.
dropdownItems.Clear();
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.EZ2_SKIN).ToLive(realm));
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.SBI_SKIN).ToLive(realm));
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.ARGON_SKIN).ToLive(realm));
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.ARGON_PRO_SKIN).ToLive(realm));
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.TRIANGLES_SKIN).ToLive(realm));

View File

@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mods
sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange);
}
public double ApplyToRate(double time, double rate) => rate * SpeedChange.Value;
public virtual double ApplyToRate(double time, double rate) => rate * SpeedChange.Value;
public override Type[] IncompatibleMods => new[] { typeof(ModTimeRamp), typeof(ModAdaptiveSpeed), typeof(ModRateAdjust) };

View File

@@ -5,6 +5,7 @@ namespace osu.Game.Rulesets.Mods
{
public enum ModType
{
CustomMod,
DifficultyReduction,
DifficultyIncrease,
Conversion,

View File

@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Rulesets.Scoring
@@ -13,9 +14,9 @@ namespace osu.Game.Rulesets.Scoring
/// <summary>
/// A structure containing timing data for hit window based gameplay.
/// </summary>
public class HitWindows
public class HitWindows : IHitWindows
{
private static readonly DifficultyRange[] base_ranges =
public static DifficultyRange[] BaseRanges =
{
new DifficultyRange(HitResult.Perfect, 22.4D, 19.4D, 13.9D),
new DifficultyRange(HitResult.Great, 64, 49, 34),
@@ -25,12 +26,33 @@ namespace osu.Game.Rulesets.Scoring
new DifficultyRange(HitResult.Miss, 188, 173, 158),
};
private double perfect;
private double great;
private double good;
private double ok;
private double meh;
private double miss;
private static double perfect;
private static double great;
private static double good;
private static double ok;
private static double meh;
private static double miss;
private static bool isModActive;
public static void SetCustomRanges(IHitWindows? customHitWindows)
{
if (isModActive && customHitWindows != null)
{
BaseRanges = customHitWindows.GetRanges();
}
}
public static void SetModActive(bool isActive)
{
isModActive = isActive;
}
public enum HitMode
{
Standardised,
Classic
}
/// <summary>
/// An empty <see cref="HitWindows"/> with only <see cref="HitResult.Miss"/> and <see cref="HitResult.Perfect"/>.
@@ -180,7 +202,7 @@ namespace osu.Game.Rulesets.Scoring
/// Retrieve a valid list of <see cref="DifficultyRange"/>s representing hit windows.
/// Defaults are provided but can be overridden to customise for a ruleset.
/// </summary>
protected virtual DifficultyRange[] GetRanges() => base_ranges;
public virtual DifficultyRange[] GetRanges() => BaseRanges;
private class EmptyHitWindows : HitWindows
{
@@ -202,7 +224,7 @@ namespace osu.Game.Rulesets.Scoring
return false;
}
protected override DifficultyRange[] GetRanges() => ranges;
public override DifficultyRange[] GetRanges() => ranges;
}
}

View File

@@ -6,9 +6,11 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using MessagePack;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Extensions;
using osu.Game.Localisation;
using osu.Game.Rulesets.Judgements;
@@ -38,6 +40,16 @@ namespace osu.Game.Rulesets.Scoring
private const double accuracy_cutoff_c = 0.7;
private const double accuracy_cutoff_d = 0;
public Bindable<double> AccS { get; set; } = null!;
public Bindable<double> AccA { get; set; } = null!;
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
AccS = config.GetBindable<double>(OsuSetting.AccuracyCutoffS);
AccA = config.GetBindable<double>(OsuSetting.AccuracyCutoffA);
}
/// <summary>
/// Whether <see cref="HitEvents"/> should be populated during application of results.
/// </summary>
@@ -532,9 +544,9 @@ namespace osu.Game.Rulesets.Scoring
{
if (accuracy == accuracy_cutoff_x)
return ScoreRank.X;
if (accuracy >= accuracy_cutoff_s)
if (accuracy >= accuracy_cutoff_s) //AccS.Value)
return ScoreRank.S;
if (accuracy >= accuracy_cutoff_a)
if (accuracy >= accuracy_cutoff_a) //AccA.Value)
return ScoreRank.A;
if (accuracy >= accuracy_cutoff_b)
return ScoreRank.B;

View File

@@ -105,10 +105,10 @@ namespace osu.Game.Screens.Play
bool isRotated = absRotation > allowance && absRotation < (180 - allowance);
keyNameText.Anchor =
keyNameText.Origin = isRotated ? Anchor.TopCentre : Anchor.TopLeft;
keyNameText.Origin = Anchor.TopCentre;
countText.Anchor =
countText.Origin = isRotated ? Anchor.BottomCentre : Anchor.BottomLeft;
countText.Origin = Anchor.BottomCentre;
}
protected override void Activate(bool forwardPlayback = true)

View File

@@ -19,7 +19,7 @@ namespace osu.Game.Screens.Play.HUD
{
public partial class ArgonComboCounter : ComboCounter
{
protected ArgonCounterTextComponent Text = null!;
public ArgonCounterTextComponent Text = null!;
protected override double RollingDuration => 250;

View File

@@ -470,13 +470,13 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
base.PrepareForUse();
const int judgement_fade_in_duration = 100;
const int judgement_fade_out_duration = 5000;
const int judgement_fade_out_duration = 1200;
Alpha = 0;
Width = 0;
this
.FadeTo(0.6f, judgement_fade_in_duration, Easing.OutQuint)
.FadeTo(0.8f, judgement_fade_in_duration, Easing.OutQuint)
.ResizeWidthTo(1, judgement_fade_in_duration, Easing.OutQuint)
.Then()
.FadeOut(judgement_fade_out_duration)

View File

@@ -46,7 +46,7 @@ namespace osu.Game.Screens.Select.Carousel
/// </summary>
public const float HEIGHT = height + CAROUSEL_BEATMAP_SPACING;
private const float height = MAX_HEIGHT * 0.6f;
private const float height = MAX_HEIGHT * 1f;
private readonly BeatmapInfo beatmapInfo;
@@ -100,6 +100,15 @@ namespace osu.Game.Screens.Select.Carousel
Item = panel;
}
private IBeatmap playableBeatmap = null!;
private WorkingBeatmap workingBeatmap = null!;
private Dictionary<int, int> columnNoteCounts = new Dictionary<int, int>();
private readonly Dictionary<string, (double averageKps, double maxKps, List<double> kpsList)> kpsCache = new Dictionary<string, (double, double, List<double>)>();
// private readonly Dictionary<string, Dictionary<int, int>> columnNoteCountsCache = new Dictionary<string, Dictionary<int, int>>();
private (double averageKps, double maxKps, List<double> kpsList) kpsResult;
[BackgroundDependencyLoader]
private void load(SongSelect? songSelect)
{
@@ -112,7 +121,37 @@ namespace osu.Game.Screens.Select.Carousel
}
if (manager != null)
{
hideRequested = manager.Hide;
workingBeatmap = manager.GetWorkingBeatmap(beatmapInfo);
playableBeatmap = workingBeatmap.GetPlayableBeatmap(ruleset.Value, mods.Value);
}
if (mods.Value == null)
{
// kpsCache.Clear();
string beatmapHash = beatmapInfo.Hash;
if (!kpsCache.TryGetValue(beatmapHash, out kpsResult))
{
kpsResult = ILAsBmCal.GetKps(playableBeatmap);
kpsCache[beatmapHash] = kpsResult;
}
// if (!columnNoteCountsCache.TryGetValue(beatmapHash, out columnNoteCounts!))
// {
// columnNoteCounts = ILAsBmCal.GetColumnNoteCounts(playableBeatmap);
// columnNoteCountsCache[beatmapHash] = columnNoteCounts;
// }
kpsResult = ILAsBmCal.GetKps(playableBeatmap);
}
else
{
columnNoteCounts = ILAsBmCal.GetColumnNoteCounts(playableBeatmap);
kpsResult = ILAsBmCal.GetKps(playableBeatmap);
}
var (averageKps, maxKps, kpsList) = kpsResult;
Header.Children = new Drawable[]
{
@@ -129,38 +168,81 @@ namespace osu.Game.Screens.Select.Carousel
},
new FillFlowContainer
{
Padding = new MarginPadding(5),
Padding = new MarginPadding(2),
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Children = new Drawable[]
{
difficultyIcon = new DifficultyIcon(beatmapInfo)
new FillFlowContainer
{
TooltipType = DifficultyIconTooltipType.None,
Scale = new Vector2(1.8f),
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
difficultyIcon = new DifficultyIcon(beatmapInfo)
{
TooltipType = DifficultyIconTooltipType.None,
Scale = new Vector2(1.8f),
},
new Box
{
RelativeSizeAxes = Axes.X,
Height = 5,
Colour = Colour4.Transparent
},
new TopLocalRank(beatmapInfo),
}
},
new FillFlowContainer
{
Padding = new MarginPadding { Left = 5 },
Padding = new MarginPadding { Left = 2 },
Direction = FillDirection.Vertical,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Children = new Drawable[]
{
new OsuSpriteText
{
Text = "KPS: ",
Font = OsuFont.GetFont(size: 14),
Colour = Colour4.GhostWhite,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
},
kpsList != null && kpsList.Count > 0
? new LineGraph
{
Size = new Vector2(450, 10),
Colour = OsuColour.Gray(0.8f),
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Values = kpsList.Select(kps => (float)kps).ToArray()
}
: null,
}.Where(child => child != null).ToArray(),
},
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
Spacing = new Vector2(4, 0),
AutoSizeAxes = Axes.Both,
Children = new[]
Children = new Drawable[]
{
// new TopLocalRank(beatmapInfo),
keyCountText = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 20),
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Alpha = 0,
Colour = Colour4.Pink
},
new OsuSpriteText
{
@@ -173,7 +255,8 @@ namespace osu.Game.Screens.Select.Carousel
{
Text = BeatmapsetsStrings.ShowDetailsMappedBy(beatmapInfo.Metadata.Author.Username),
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
Origin = Anchor.BottomLeft,
Colour = Colour4.LightGoldenrodYellow
},
}
},
@@ -181,29 +264,120 @@ namespace osu.Game.Screens.Select.Carousel
{
Direction = FillDirection.Horizontal,
Spacing = new Vector2(4, 0),
Scale = new Vector2(0.8f),
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new TopLocalRank(beatmapInfo),
starCounter = new StarCounter()
new OsuSpriteText
{
Text = $"[{beatmapInfo.StarRating:F2}*] ",
Font = OsuFont.GetFont(size: 18),
Colour = Colour4.LightGoldenrodYellow,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
},
starCounter = new StarCounter
{
Scale = new Vector2(0.6f),
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft
},
new OsuSpriteText
{
Text = $" KPS: {averageKps:F2} Avg {maxKps:F2} Max",
Font = OsuFont.GetFont(size: 18),
Colour = Colour4.CornflowerBlue,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft
},
}
}
},
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
Spacing = new Vector2(4, 0),
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new OsuSpriteText
{
Text = "[Notes] ",
Font = OsuFont.GetFont(size: 14),
Colour = Colour4.GhostWhite,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
},
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Children = columnNoteCounts
.OrderBy(c => c.Key)
.Select((c, index) => new FillFlowContainer
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new OsuSpriteText
{
Text = $"{index + 1}/",
Font = OsuFont.GetFont(size: 12),
Colour = Colour4.Gray,
},
new OsuSpriteText
{
Text = $"{c.Value} ",
Font = OsuFont.GetFont(size: 14),
Colour = Colour4.LightCoral,
}
}
}).ToArray()
}
}
},
}
}
},
}
}
},
};
// }
}
protected override void LoadComplete()
{
base.LoadComplete();
updateKeyCount();
ruleset.BindValueChanged(_ => updateKeyCount());
mods.BindValueChanged(_ => updateKeyCount());
mods.BindValueChanged(_ =>
{
updateKeyCount();
});
}
// private void updateCalculations()
// {
// ILegacyRuleset legacyRuleset = (ILegacyRuleset)ruleset.Value.CreateInstance();
// IBeatmap playableBeatmap;
//
// try
// {
// playableBeatmap = workingBeatmap.GetPlayableBeatmap(ruleset.Value, mods.Value);
// }
// catch (BeatmapInvalidForRulesetException)
// {
// playableBeatmap = workingBeatmap.GetPlayableBeatmap(workingBeatmap.BeatmapInfo.Ruleset, mods.Value);
// }
//
// columnNoteCounts = ILAsBmCal.GetColumnNoteCounts(playableBeatmap);
//
// int keyCount = legacyRuleset.GetKeyCount(beatmapInfo, mods.Value);
//
// // Schedule(() =>
// // {
// // columnNoteCounts = ILAsBmCal.GetColumnNoteCounts(playableBeatmap);
// // });
// }
protected override void Selected()
{
base.Selected();
@@ -271,8 +445,21 @@ namespace osu.Game.Screens.Select.Carousel
// Eventually this should be handled in a more modular way, allowing rulesets to add more information to the panel.
ILegacyRuleset legacyRuleset = (ILegacyRuleset)ruleset.Value.CreateInstance();
try
{
playableBeatmap = workingBeatmap.GetPlayableBeatmap(ruleset.Value, mods.Value);
}
catch (EntryPointNotFoundException)
{
playableBeatmap = workingBeatmap.GetPlayableBeatmap(workingBeatmap.BeatmapInfo.Ruleset, mods.Value);
}
int keyCount = legacyRuleset.GetKeyCount(beatmapInfo, mods.Value);
string keyCountTextValue = ILAsBmCal.GetScratch(playableBeatmap, keyCount);
columnNoteCounts = ILAsBmCal.GetColumnNoteCounts(playableBeatmap);
kpsResult = ILAsBmCal.GetKps(playableBeatmap);
keyCountText.Alpha = 1;
keyCountText.Text = $"[{legacyRuleset.GetKeyCount(beatmapInfo, mods.Value)}K]";
keyCountText.Text = keyCountTextValue;
}
else
keyCountText.Alpha = 0;

View File

@@ -1,7 +1,6 @@
// 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.
using System.ComponentModel;
using osu.Framework.Localisation;
using osu.Game.Resources.Localisation.Web;
@@ -12,22 +11,22 @@ namespace osu.Game.Screens.Select.Filter
[LocalisableDescription(typeof(BeatmapsStrings), nameof(BeatmapsStrings.ListingSearchSortingArtist))]
Artist,
[Description("Author")]
[LocalisableDescription(typeof(BeatmapsStrings), nameof(BeatmapsStrings.ListingSearchSortingAuthor))]
Author,
[LocalisableDescription(typeof(SortStrings), nameof(SortStrings.ArtistTracksBpm))]
BPM,
[Description("Date Submitted")]
[LocalisableDescription(typeof(SortStrings), nameof(SortStrings.DateSubmitted))]
DateSubmitted,
[Description("Date Added")]
[LocalisableDescription(typeof(SortStrings), nameof(SortStrings.DateAdded))]
DateAdded,
[Description("Date Ranked")]
[LocalisableDescription(typeof(SortStrings), nameof(SortStrings.DateRanked))]
DateRanked,
[Description("Last Played")]
[LocalisableDescription(typeof(SortStrings), nameof(SortStrings.LastPlayed))]
LastPlayed,
[LocalisableDescription(typeof(BeatmapsStrings), nameof(BeatmapsStrings.ListingSearchSortingDifficulty))]
@@ -40,7 +39,7 @@ namespace osu.Game.Screens.Select.Filter
// [Description("Rank Achieved")]
// RankAchieved,
[Description("Source")]
[LocalisableDescription(typeof(SortStrings), nameof(SortStrings.ArtistTracksSource))]
Source,
[LocalisableDescription(typeof(BeatmapsStrings), nameof(BeatmapsStrings.ListingSearchSortingTitle))]

View File

@@ -1,4 +1,4 @@
// 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.
#nullable disable
@@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
@@ -34,7 +35,7 @@ namespace osu.Game.Screens.Select
{
public partial class FilterControl : Container
{
public const float HEIGHT = 2 * side_margin + 120;
public const float HEIGHT = 4 * side_margin + 120;
private const float side_margin = 10;
@@ -54,6 +55,9 @@ namespace osu.Game.Screens.Select
private FilterControlTextBox searchTextBox;
private CollectionDropdown collectionDropdown;
// private OsuTabControl<SelectEzMode> ezModeTabs;
private Bindable<SelectEzMode> ezMode;
[CanBeNull]
private FilterCriteria currentCriteria;
@@ -71,6 +75,22 @@ namespace osu.Game.Screens.Select
CollectionBeatmapMD5Hashes = collectionDropdown.Current.Value?.Collection?.PerformRead(c => c.BeatmapMD5Hashes).ToImmutableHashSet()
};
if (ezMode?.Value != null && ezMode.Value != SelectEzMode.All)
{
float keyCount;
if (float.TryParse(EzModeHelper.GetKeyCountFromEzMode(ezMode.Value).ToString(CultureInfo.InvariantCulture), out keyCount))
{
criteria.CircleSize = new FilterCriteria.OptionalRange<float>
{
Min = keyCount,
Max = keyCount,
IsLowerInclusive = true,
IsUpperInclusive = true
};
}
}
if (!minimumStars.IsDefault)
criteria.UserStarDifficulty.Min = minimumStars.Value;
@@ -91,6 +111,7 @@ namespace osu.Game.Screens.Select
{
sortMode = config.GetBindable<SortMode>(OsuSetting.SongSelectSortingMode);
groupMode = config.GetBindable<GroupMode>(OsuSetting.SongSelectGroupingMode);
ezMode = config.GetBindable<SelectEzMode>(OsuSetting.SelectEzMode);
Children = new Drawable[]
{
@@ -169,6 +190,45 @@ namespace osu.Game.Screens.Select
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
},
},
}
},
new GridContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
ColumnDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension(GridSizeMode.Absolute, OsuTabControl<SortMode>.HORIZONTAL_SPACING),
new Dimension(),
new Dimension(GridSizeMode.Absolute, OsuTabControl<SortMode>.HORIZONTAL_SPACING),
new Dimension(GridSizeMode.AutoSize),
},
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
Content = new[]
{
new[]
{
new OsuSpriteText
{
Text = "Keys",
Font = OsuFont.GetFont(size: 12),
Margin = new MarginPadding(5),
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
},
Empty(),
new OsuTabControl<SelectEzMode>
{
RelativeSizeAxes = Axes.X,
Height = 24,
AutoSort = false,
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
AccentColour = colours.BlueLight,
Current = { BindTarget = ezMode }
},
}
}
},
@@ -231,6 +291,10 @@ namespace osu.Game.Screens.Select
updateCriteria();
});
// ezModeTabs.Current.BindValueChanged(OnEzModeChanged, true);
// ezMode?.BindValueChanged(_ => updateCriteria());
ezMode.ValueChanged += _ => updateCriteria();
groupMode.BindValueChanged(_ => updateCriteria());
sortMode.BindValueChanged(_ => updateCriteria());
@@ -239,6 +303,12 @@ namespace osu.Game.Screens.Select
updateCriteria();
}
// private void OnEzModeChanged(ValueChangedEvent<SelectEzMode> args)
// {
// string filterString = EzModeHelper.GenerateFilterString(args.NewValue);
// // currentCriteria!.CircleSize.Min = currentCriteria.CircleSize.Max = EzModeHelper.GetKeyCountFromEzMode(args.NewValue);
// CurrentTextSearch.Value = filterString;
// }
public void Deactivate()
{
searchTextBox.ReadOnly = true;
@@ -307,3 +377,48 @@ namespace osu.Game.Screens.Select
}
}
}
// private void OnEzModeChanged(ValueChangedEvent<SelectEzMode> args)
// {
// string filterString = EzModeHelper.GenerateFilterString(args.NewValue);
// FilterCriteria criteria = new FilterCriteria
// {
// Group = groupMode?.Value ?? default,
// Sort = sortMode?.Value ?? default,
// AllowConvertedBeatmaps = showConverted?.Value ?? false,
// EzMode = ezMode?.Value ?? default,
// Ruleset = ruleset?.Value,
// Mods = mods?.Value ?? new List<Mod>(),
// CollectionBeatmapMD5Hashes = collectionDropdown?.Current.Value?.Collection?.PerformRead(c => c.BeatmapMD5Hashes).ToImmutableHashSet()
// };
// FilterQueryParser.ApplyQueries(criteria, filterString);
// // CurrentTextSearch.Value = filterString;
// }
// public event Action<SelectEzMode, bool> Clicked;
// protected override bool OnClick(ClickEvent e)
// {
// if (e.Button == MouseButton.Left || e.Button == MouseButton.Right)
// {
// // 确定点击的是哪个模式
// var selectedItem = ezModeTabs.Current.Value;
//
// if (e.Button == MouseButton.Left)
// {
// Clicked?.Invoke(selectedItem, true);
// }
// // else if (e.Button == MouseButton.Right)
// // {
// // if (control.GetSelectedMode() = selectedItem)
// // {
// // control.ToggleMode(selectedItem);
// // Clicked?.Invoke(selectedItem, false);
// // }
// // }
//
// return true;
// }
//
// return base.OnClick(e);
// }

View File

@@ -27,6 +27,7 @@ namespace osu.Game.Screens.Select
public BeatmapSetInfo? SelectedBeatmapSet;
// public List<float> EzK { get; set; } = new List<float>();
public OptionalRange<double> StarDifficulty;
public OptionalRange<float> ApproachRate;
public OptionalRange<float> DrainRate;

View File

@@ -33,9 +33,36 @@ namespace osu.Game.Screens.Select
criteria.SearchText = query;
}
// private static readonly Regex query_syntax_regex = new Regex(
// @"\b(?<key>\w+)(?<op>(:|=|(>|<)(:|=)?))(?<value>("".*""[!]?)|(\S+(\|\S+)*))",
// RegexOptions.Compiled | RegexOptions.IgnoreCase);
//
// internal static void ApplyQueries(FilterCriteria criteria, string query)
// {
// foreach (Match match in query_syntax_regex.Matches(query))
// {
// string key = match.Groups["key"].Value.ToLowerInvariant();
// var op = parseOperator(match.Groups["op"].Value);
// string value = match.Groups["value"].Value;
//
// string[] values = value.Split('|');
//
// foreach (string val in values)
// {
// if (tryParseKeywordCriteria(criteria, key, val, op))
// query = query.Replace(match.ToString(), "");
// }
// }
//
// criteria.SearchText = query;
// }
private static bool tryParseKeywordCriteria(FilterCriteria criteria, string key, string value, Operator op)
{
// string[] values = value.Split('|');
// foreach (string val in values)
// {
switch (key)
{
case "star":
@@ -53,6 +80,18 @@ namespace osu.Game.Screens.Select
case "cs":
return TryUpdateCriteriaRange(ref criteria.CircleSize, op, value);
// case "EzK":
// if (float.TryParse(val, out float csValue))
// {
// criteria.EzK.Add(csValue);
// }
// else
// {
// return false;
// }
//
// break;
case "od":
return TryUpdateCriteriaRange(ref criteria.OverallDifficulty, op, value);
@@ -119,6 +158,9 @@ namespace osu.Game.Screens.Select
default:
return criteria.RulesetCriteria?.TryParseCustomKeywordCriteria(key, op, value) ?? false;
}
// }
//
// return true;
}
private static Operator parseOperator(string value)

View File

@@ -18,6 +18,10 @@ namespace osu.Game.Screens.Select
{
public readonly BeatmapLeaderboard Leaderboard;
public static WorkingBeatmap SelectedBeatmap;
public static BeatmapInfo SelectedBeatmapInfo;
public override WorkingBeatmap Beatmap
{
get => base.Beatmap;
@@ -26,6 +30,9 @@ namespace osu.Game.Screens.Select
base.Beatmap = value;
Leaderboard.BeatmapInfo = value is DummyWorkingBeatmap ? null : value?.BeatmapInfo;
SelectedBeatmap = value;
SelectedBeatmapInfo = value?.BeatmapInfo;
}
}

View File

@@ -49,8 +49,8 @@ namespace osu.Game.Skinning
{
AutoSizeAxes = Axes.Both;
Anchor = Anchor.BottomLeft;
Origin = Anchor.BottomLeft;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Margin = new MarginPadding(10);
@@ -67,14 +67,14 @@ namespace osu.Game.Skinning
{
Alpha = 0,
Blending = BlendingParameters.Additive,
Anchor = Anchor.BottomLeft,
Anchor = Anchor.BottomCentre,
BypassAutoSizeAxes = Axes.Both,
},
displayedCountSpriteText = new LegacySpriteText(LegacyFont.Combo)
{
Alpha = 0,
AlwaysPresent = true,
Anchor = Anchor.BottomLeft,
Anchor = Anchor.BottomCentre,
BypassAutoSizeAxes = Axes.Both,
},
}
@@ -124,14 +124,14 @@ namespace osu.Game.Skinning
private void updateLayout()
{
const float font_height_ratio = 0.625f;
const float vertical_offset = 9;
// const float font_height_ratio = 0.625f;
// const float vertical_offset = 9;
displayedCountSpriteText.OriginPosition = new Vector2(0, font_height_ratio * displayedCountSpriteText.Height + vertical_offset);
displayedCountSpriteText.Position = new Vector2(0, -(1 - font_height_ratio) * displayedCountSpriteText.Height + vertical_offset);
// displayedCountSpriteText.OriginPosition = new Vector2(displayedCountSpriteText.Width / 2, displayedCountSpriteText.Height / 2);
// displayedCountSpriteText.Position = new Vector2(0, 0);
popOutCount.OriginPosition = new Vector2(3, font_height_ratio * popOutCount.Height + vertical_offset); // In stable, the bigger pop out scales a bit to the left
popOutCount.Position = new Vector2(0, -(1 - font_height_ratio) * popOutCount.Height + vertical_offset);
popOutCount.Position = new Vector2(0, 8);
// popOutCount.Position = new Vector2(0, 0);
counterContainer.Size = displayedCountSpriteText.Size;
}

View File

@@ -379,8 +379,8 @@ namespace osu.Game.Skinning
if (combo != null)
{
combo.Anchor = Anchor.BottomLeft;
combo.Origin = Anchor.BottomLeft;
combo.Anchor = Anchor.Centre;
combo.Origin = Anchor.Centre;
combo.Scale = new Vector2(1.28f);
pos += new Vector2(10, -(combo.DrawHeight * 1.56f + 20) * combo.Scale.X);
@@ -388,8 +388,8 @@ namespace osu.Game.Skinning
if (spectatorList != null)
{
spectatorList.Anchor = Anchor.BottomLeft;
spectatorList.Origin = Anchor.BottomLeft;
spectatorList.Anchor = Anchor.Centre;
spectatorList.Origin = Anchor.Centre;
spectatorList.Position = pos;
}
})

View File

@@ -21,6 +21,8 @@ namespace osu.Game.Skinning
internal static readonly Guid ARGON_PRO_SKIN = new Guid("9FC9CF5D-0F16-4C71-8256-98868321AC43");
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 EZ2_SKIN = new Guid("fc372386-381d-4f8e-897a-c1d89ef39f9c");
internal static readonly Guid SBI_SKIN = new Guid("fc372386-381d-4f8e-897a-c1d89ef39f2c");
[PrimaryKey]
[JsonProperty]

View File

@@ -95,6 +95,8 @@ namespace osu.Game.Skinning
trianglesSkin = new TrianglesSkin(this),
argonSkin = new ArgonSkin(this),
new ArgonProSkin(this),
new Ez2Skin(this),
new SbISkin(this),
};
// Ensure the default entries are present.

View File

@@ -119,6 +119,8 @@ namespace osu.Game.Skinning
// Temporarily used to exclude undesirable ISkin implementations
static bool isUserSkin(ISkin skin)
=> skin.GetType() == typeof(TrianglesSkin)
|| skin.GetType() == typeof(Ez2Skin)
|| skin.GetType() == typeof(SbISkin)
|| skin.GetType() == typeof(ArgonProSkin)
|| skin.GetType() == typeof(ArgonSkin)
|| skin.GetType() == typeof(DefaultLegacySkin)

View File

@@ -35,7 +35,7 @@ namespace osu.Game.Storyboards.Drawables
protected override Container<DrawableStoryboardLayer> Content { get; }
protected override Vector2 DrawScale => new Vector2((Parent?.DrawHeight ?? 0) / 480);
protected override Vector2 DrawScale => new Vector2(Parent!.DrawWidth / 640);
public override bool RemoveCompletedTransforms => false;
@@ -67,7 +67,9 @@ namespace osu.Game.Storyboards.Drawables
bool onlyHasVideoElements = Storyboard.Layers.SelectMany(l => l.Elements).All(e => e is StoryboardVideo);
Width = Height * (storyboard.Beatmap.WidescreenStoryboard || onlyHasVideoElements ? 16 / 9f : 4 / 3f);
// Width = Height * (storyboard.BeatmapInfo.WidescreenStoryboard || onlyHasVideoElements ? 9 / 16f : 3 / 4f);
// Width = Parent!.DrawWidth; // Adjust width to match parent's width
Height = Width * (storyboard.Beatmap.WidescreenStoryboard || onlyHasVideoElements ? 9 / 16f : 3 / 4f);
Anchor = Anchor.Centre;
Origin = Anchor.Centre;

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Project">
<TargetFramework>net8.0</TargetFramework>
<OutputType>Library</OutputType>
@@ -18,7 +18,12 @@
</None>
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="asio" Version="1.10.8" />
<PackageReference Include="BASS" Version="2.4.12.1" />
<PackageReference Include="BASS.ASIO" Version="1.3.1.2" />
<PackageReference Include="BASS.Native" Version="2.4.13.9" />
<PackageReference Include="DiffPlex" Version="1.7.2" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.72" />
<PackageReference Include="Humanizer" Version="2.14.1" />
@@ -36,18 +41,31 @@
</PackageReference>
<PackageReference Include="Realm" Version="20.1.0" />
<PackageReference Include="ppy.osu.Framework" Version="2025.313.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2025.313.0" />
<!-- <PackageReference Include="ppy.osu.Game.Resources" Version="2025.313.0" />-->
<PackageReference Include="Sentry" Version="5.1.1" />
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
<PackageReference Include="SharpCompress" Version="0.39.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.10" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="TagLibSharp" Version="2.3.0" />
<ProjectReference Include="..\..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
<!-- Required since Veldrid references a library that depends on Microsoft.DotNet.PlatformAbstractions (2.0.3), which doesn't play nice with Realm. -->
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
<PackageReference Include="System.Runtime.Handles" Version="4.3.0" />
</ItemGroup>
<!-- <ProjectReference Include="..\..\osu-framework\osu.Framework\osu.Framework.csproj" />-->
<ItemGroup>
<Compile Remove="Screens\Edit\EditorManiaPlayableFeild.cs" />
<Compile Remove="Screens\Edit\EditorManiaPlayfield.cs" />
<Compile Remove="Screens\OnlinePlay\Components\RoomManager.cs" />
<Compile Remove="Screens\OnlinePlay\Components\RoomPollingComponent.cs" />
<Compile Remove="Screens\OnlinePlay\Components\SelectionPollingComponent.cs" />
<Compile Remove="Screens\OnlinePlay\Multiplayer\MultiplayerRoomManager.cs" />
<Compile Remove="Screens\SelectV2\BeatmapSetPanel.cs" />
<Compile Remove="Tests\Visual\Multiplayer\TestMultiplayerRoomManager.cs" />
</ItemGroup>
</Project>

35
osu.sln
View File

@@ -56,10 +56,9 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{10DF8F12-50FD-45D8-8A38-17BA764BF54D}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.globalconfig = .globalconfig
Directory.Build.props = Directory.Build.props
osu.Android.props = osu.Android.props
osu.iOS.props = osu.iOS.props
global.json = global.json
CodeAnalysis\osu.ruleset = CodeAnalysis\osu.ruleset
osu.sln.DotSettings = osu.sln.DotSettings
osu.TestProject.props = osu.TestProject.props
EndProjectSection
@@ -100,6 +99,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CodeAnalysis", "CodeAnalysi
CodeAnalysis\osu.globalconfig = CodeAnalysis\osu.globalconfig
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework", "..\osu-framework\osu.Framework\osu.Framework.csproj", "{0E2D0BC7-BFB9-4638-8F65-7F4576312ADE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework.NativeLibs", "..\osu-framework\osu.Framework.NativeLibs\osu.Framework.NativeLibs.csproj", "{3635B81B-F91C-4575-867C-6DC83CA175EA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework.Android", "..\osu-framework\osu.Framework.Android\osu.Framework.Android.csproj", "{AC291F03-507A-41BD-A40F-90C98337173A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework.iOS", "..\osu-framework\osu.Framework.iOS\osu.Framework.iOS.csproj", "{2F48D5D2-4576-4E64-8DF1-B1707A362D53}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Resources", "..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj", "{18ED4ABC-6064-46F1-9A05-4E0BE88A635A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -254,6 +263,26 @@ Global
{1743BF7C-E6AE-4A06-BAD9-166D62894303}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1743BF7C-E6AE-4A06-BAD9-166D62894303}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1743BF7C-E6AE-4A06-BAD9-166D62894303}.Release|Any CPU.Build.0 = Release|Any CPU
{0E2D0BC7-BFB9-4638-8F65-7F4576312ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E2D0BC7-BFB9-4638-8F65-7F4576312ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E2D0BC7-BFB9-4638-8F65-7F4576312ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E2D0BC7-BFB9-4638-8F65-7F4576312ADE}.Release|Any CPU.Build.0 = Release|Any CPU
{3635B81B-F91C-4575-867C-6DC83CA175EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3635B81B-F91C-4575-867C-6DC83CA175EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3635B81B-F91C-4575-867C-6DC83CA175EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3635B81B-F91C-4575-867C-6DC83CA175EA}.Release|Any CPU.Build.0 = Release|Any CPU
{AC291F03-507A-41BD-A40F-90C98337173A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC291F03-507A-41BD-A40F-90C98337173A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC291F03-507A-41BD-A40F-90C98337173A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC291F03-507A-41BD-A40F-90C98337173A}.Release|Any CPU.Build.0 = Release|Any CPU
{2F48D5D2-4576-4E64-8DF1-B1707A362D53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F48D5D2-4576-4E64-8DF1-B1707A362D53}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F48D5D2-4576-4E64-8DF1-B1707A362D53}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F48D5D2-4576-4E64-8DF1-B1707A362D53}.Release|Any CPU.Build.0 = Release|Any CPU
{18ED4ABC-6064-46F1-9A05-4E0BE88A635A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18ED4ABC-6064-46F1-9A05-4E0BE88A635A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18ED4ABC-6064-46F1-9A05-4E0BE88A635A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18ED4ABC-6064-46F1-9A05-4E0BE88A635A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE