维护代码质量,删除无用代码

This commit is contained in:
LA
2026-02-15 18:37:50 +08:00
parent 11fe2d5eb5
commit 446419c03b
45 changed files with 306 additions and 295 deletions

View File

@@ -49,15 +49,15 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
// Public API similar to SRCalculator
public static double CalculateSR(IBeatmap beatmap)
{
return ComputeInternalXxySR(beatmap, 1.0).sr;
return computeInternalXxySR(beatmap, 1.0).sr;
}
public static double CalculateSR(IBeatmap beatmap, double clockRate)
{
return ComputeInternalXxySR(beatmap, clockRate).sr;
return computeInternalXxySR(beatmap, clockRate).sr;
}
private static (double sr, Dictionary<string, long> times) ComputeInternalXxySR(IBeatmap beatmap, double clockRate = 1.0)
private static (double sr, Dictionary<string, long> times) computeInternalXxySR(IBeatmap beatmap, double clockRate = 1.0)
{
var stopwatch = Stopwatch.StartNew();
ManiaBeatmap maniaBeatmap = (ManiaBeatmap)beatmap;
@@ -217,7 +217,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
double[][] usage = new double[keyCount][];
for (int k = 0; k < keyCount; k++) usage[k] = new double[baseCorners.Length];
double base_contribution = Tunables.KeyUsageBaseContribution;
double baseContribution = Tunables.KeyUsageBaseContribution;
double falloff = Tunables.KeyUsageBaseContribution / (400.0 * 400.0);
foreach (var note in notes)
@@ -233,7 +233,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
int duration = endTime - startTime;
double clampedDuration = Math.Min(duration, Tunables.KeyUsageDurationCap);
double extension = clampedDuration / Tunables.KeyUsageExtensionDivisor;
double contribution = base_contribution + extension;
double contribution = baseContribution + extension;
for (int idx = left; idx < right; idx++) usage[note.Column][idx] += contribution;
@@ -241,7 +241,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
{
double offset = baseCorners[idx] - startTime;
double falloffContribution = falloff * Math.Pow(offset, 2);
double value = base_contribution - falloffContribution;
double value = baseContribution - falloffContribution;
double clamped = Math.Max(value, 0);
usage[note.Column][idx] += clamped;
}
@@ -250,7 +250,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
{
double offset = baseCorners[idx] - endTime;
double falloffContribution = falloff * Math.Pow(offset, 2);
double value = base_contribution - falloffContribution;
double value = baseContribution - falloffContribution;
double clamped = Math.Max(value, 0);
usage[note.Column][idx] += clamped;
}

View File

@@ -3,18 +3,14 @@
using System;
using System.Collections.Generic;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.IO;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.LAsEZMania.Analysis;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Tests.Visual;
@@ -24,9 +20,9 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
{
public partial class TestSceneSRTune : OsuTestScene
{
private FillFlowContainer listContainer = null!;
private Dictionary<string, double> last = new Dictionary<string, double>();
private Dictionary<string, double> current = new Dictionary<string, double>();
private readonly FillFlowContainer listContainer;
private readonly Dictionary<string, double> last = new Dictionary<string, double>();
private readonly Dictionary<string, double> current = new Dictionary<string, double>();
// exposed tuning parameters (initialized from Tunables defaults)
private double ln_weight = SRCalculatorTunable.Tunables.FinalLNToNotesFactor; // 0.0 - 1.0
@@ -75,7 +71,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
// save current settings to "last" snapshot
AddStep("Save as last settings", () =>
{
lastSettings = (SRCalculatorTunable.Tunables.FinalLNToNotesFactor, SRCalculatorTunable.Tunables.FinalLNLenCap, SRCalculatorTunable.Tunables.TotalNotesOffset, SRCalculatorTunable.Tunables.PBarLnMultiplier, SRCalculatorTunable.Tunables.JackPenaltyMultiplier, SRCalculatorTunable.Tunables.FinalScale);
lastSettings = (SRCalculatorTunable.Tunables.FinalLNToNotesFactor, SRCalculatorTunable.Tunables.FinalLNLenCap, SRCalculatorTunable.Tunables.TotalNotesOffset,
SRCalculatorTunable.Tunables.PBarLnMultiplier, SRCalculatorTunable.Tunables.JackPenaltyMultiplier, SRCalculatorTunable.Tunables.FinalScale);
// also snapshot last SR values from current
foreach (string k in current.Keys)
last[k] = current[k];
@@ -91,8 +88,10 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
for (int i = 0; i < 8; i++)
{
var bm = new ManiaBeatmap(new StageDefinition(4));
bm.BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = $"Sample {i + 1}" } };
var bm = new ManiaBeatmap(new StageDefinition(4))
{
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = $"Sample {i + 1}" } }
};
for (int t = 0; t < 2000; t += 250)
{
@@ -104,8 +103,11 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
}
else
{
var hold = new HoldNote { StartTime = t + i * 10, Column = i % 4 };
hold.Duration = 400 + i * 50;
var hold = new HoldNote
{
StartTime = t + i * 10, Column = i % 4,
Duration = 400 + i * 50
};
bm.HitObjects.Add(hold);
}
}
@@ -139,7 +141,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
foreach (var bm in sampleBeatmaps)
{
string id = ((BeatmapInfo)bm.BeatmapInfo).Metadata.Title!;
string id = bm.BeatmapInfo.Metadata.Title;
last[id] = 0;
current[id] = 0;
@@ -151,12 +153,12 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
Spacing = new Vector2(10f),
Children = new Drawable[]
{
new OsuSpriteText { Text = id, Width = 180, Font = new FontUsage(size:20) },
new OsuSpriteText { Text = "Last: 0", Name = "last_" + id, Font = new FontUsage(size:20) },
new OsuSpriteText { Text = "Cur: 0", Name = "cur_" + id, Font = new FontUsage(size:20) },
new OsuSpriteText { Text = id, Width = 180, Font = new FontUsage(size: 20) },
new OsuSpriteText { Text = "Last: 0", Name = "last_" + id, Font = new FontUsage(size: 20) },
new OsuSpriteText { Text = "Cur: 0", Name = "cur_" + id, Font = new FontUsage(size: 20) },
// place holders for settings display under the SRs
new OsuSpriteText { Text = "Last settings: -", Name = "last_set_" + id, Font = new FontUsage(size:20) },
new OsuSpriteText { Text = "Cur settings: -", Name = "cur_set_" + id, Font = new FontUsage(size:20) }
new OsuSpriteText { Text = "Last settings: -", Name = "last_set_" + id, Font = new FontUsage(size: 20) },
new OsuSpriteText { Text = "Cur settings: -", Name = "cur_set_" + id, Font = new FontUsage(size: 20) }
}
};
@@ -181,7 +183,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
}
// propagate slider values into SRCalculatorTunable.Tunables
TunableSyncFromSliders();
tunableSyncFromSliders();
for (int i = 0; i < sampleBeatmaps.Length; i++)
{
@@ -197,16 +199,23 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
if (curText != null) curText.Text = $"Cur: {sr:F2}";
// update settings display
var lastSetText = row?.Children[3] as SpriteText;
var curSetText = row?.Children[4] as SpriteText;
if (lastSetText != null)
lastSetText.Text = $"Last settings: ln_w={lastSettings.lnWeight:F3}, ln_cap={lastSettings.lnLenCap:F0}, off={lastSettings.offset:F0}, pbar={lastSettings.pbarCoeff:F4}, jack={lastSettings.jackMult:F1}, scale={lastSettings.scale:F3}";
if (row?.Children[3] is SpriteText lastSetText)
{
lastSetText.Text =
$"Last settings: ln_w={lastSettings.lnWeight:F3}, ln_cap={lastSettings.lnLenCap:F0}, off={lastSettings.offset:F0}, pbar={lastSettings.pbarCoeff:F4}, jack={lastSettings.jackMult:F1}, scale={lastSettings.scale:F3}";
}
if (curSetText != null)
curSetText.Text = $"Cur settings: ln_w={SRCalculatorTunable.Tunables.FinalLNToNotesFactor:F3}, ln_cap={SRCalculatorTunable.Tunables.FinalLNLenCap:F0}, off={SRCalculatorTunable.Tunables.TotalNotesOffset:F0}, pbar={SRCalculatorTunable.Tunables.PBarLnMultiplier:F4}, jack={SRCalculatorTunable.Tunables.JackPenaltyMultiplier:F1}, scale={SRCalculatorTunable.Tunables.FinalScale:F3}";
{
curSetText.Text =
$"Cur settings: ln_w={SRCalculatorTunable.Tunables.FinalLNToNotesFactor:F3}, ln_cap={SRCalculatorTunable.Tunables.FinalLNLenCap:F0}, off={SRCalculatorTunable.Tunables.TotalNotesOffset:F0}, pbar={SRCalculatorTunable.Tunables.PBarLnMultiplier:F4}, jack={SRCalculatorTunable.Tunables.JackPenaltyMultiplier:F1}, scale={SRCalculatorTunable.Tunables.FinalScale:F3}";
}
}
}
private void TunableSyncFromSliders()
private void tunableSyncFromSliders()
{
var sliders = this.ChildrenOfType<BasicSliderBar<double>>();
@@ -222,7 +231,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Analysis
}
// isolated compute method that uses exposed parameters
private double HotComputeSR(IBeatmap beatmap, double lnWeight, int lnLenCap, int offset, double pbarCoeff, double jackMult, double scale)
private double hotComputeSR(IBeatmap beatmap, double lnWeight, int lnLenCap, int offset, double pbarCoeff, double jackMult, double scale)
{
var mania = (ManiaBeatmap)beatmap;
int headCount = 0;

View File

@@ -1,15 +1,14 @@
// 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.Linq;
using System.Collections.Generic;
using System;
using System.Linq;
using NUnit.Framework;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Mods.LAsMods;
using osu.Game.Audio;
using osu.Game.Rulesets.Mania.Objects;
namespace osu.Game.Rulesets.Mania.Tests.Mods
{
@@ -20,8 +19,10 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
public void ExpansionNumericReorder_CopiesSourceColumnsAndUpdatesColumnCount()
{
// 构造一个 5k 源谱面,列上的 note 数分别为 1,2,3,4,5用于简化断言
var beatmap = new ManiaBeatmap(new StageDefinition(5));
beatmap.Difficulty = new BeatmapDifficulty { CircleSize = 5 };
var beatmap = new ManiaBeatmap(new StageDefinition(5))
{
Difficulty = new BeatmapDifficulty { CircleSize = 5 }
};
var hitObjects = new List<ManiaHitObject>();
int time = 0;
@@ -42,12 +43,20 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
}
}
beatmap.HitObjects = hitObjects.Cast<ManiaHitObject>().ToList();
beatmap.HitObjects = hitObjects.ToList();
// 应用 mod规则为 "123123123"(将生成 9 列,按 1,2,3,1,2,3,1,2,3 映射)
var mod = new ManiaModCleanColumn();
mod.EnableCustomReorder.Value = true;
mod.CustomReorderColumn.Value = "12-112233";
var mod = new ManiaModCleanColumn
{
EnableCustomReorder =
{
Value = true
},
CustomReorderColumn =
{
Value = "12-112233"
}
};
mod.ApplyToBeatmap(beatmap);
@@ -55,7 +64,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
Assert.AreEqual(9, beatmap.Difficulty.CircleSize);
// 计算每列 note 数量并验证
var counts = Enumerable.Range(0, 9).Select(t => beatmap.HitObjects.Count(h => h.Column == t)).ToArray();
int[] counts = Enumerable.Range(0, 9).Select(t => beatmap.HitObjects.Count(h => h.Column == t)).ToArray();
int[] expected = { 1, 2, 0, 1, 1, 2, 2, 3, 3 };
Assert.AreEqual(expected.Length, counts.Length);
@@ -66,8 +75,10 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
public void ReductionNumericReorder_TruncatesToSpecifiedColumns()
{
// 构造一个 9k 源谱面,列上的 note 数分别为 1..9
var beatmap = new ManiaBeatmap(new StageDefinition(9));
beatmap.Difficulty = new BeatmapDifficulty { CircleSize = 9 };
var beatmap = new ManiaBeatmap(new StageDefinition(9))
{
Difficulty = new BeatmapDifficulty { CircleSize = 9 }
};
var hitObjects = new List<ManiaHitObject>();
int time = 0;
@@ -87,17 +98,25 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
}
}
beatmap.HitObjects = hitObjects.Cast<ManiaHitObject>().ToList();
beatmap.HitObjects = hitObjects.ToList();
// 规则 "12345" 将把前 5 列复制到 5 列谱面
var mod = new ManiaModCleanColumn();
mod.EnableCustomReorder.Value = true;
mod.CustomReorderColumn.Value = "12345";
var mod = new ManiaModCleanColumn
{
EnableCustomReorder =
{
Value = true
},
CustomReorderColumn =
{
Value = "12345"
}
};
mod.ApplyToBeatmap(beatmap);
Assert.AreEqual(5, beatmap.Difficulty.CircleSize);
var counts = Enumerable.Range(0, 5).Select(t => beatmap.HitObjects.Count(h => h.Column == t)).ToArray();
int[] counts = Enumerable.Range(0, 5).Select(t => beatmap.HitObjects.Count(h => h.Column == t)).ToArray();
int[] expected = { 1, 1, 1, 1, 1 };
CollectionAssert.AreEqual(expected, counts);
}
@@ -106,23 +125,34 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
public void Operators_HoldAndClear_WorkCorrectly()
{
// 源谱面 4 列,每列 1 个 note
var beatmap = new ManiaBeatmap(new StageDefinition(4));
beatmap.Difficulty = new BeatmapDifficulty { CircleSize = 4 };
var beatmap = new ManiaBeatmap(new StageDefinition(4))
{
Difficulty = new BeatmapDifficulty { CircleSize = 4 }
};
var hitObjects = new List<ManiaHitObject>();
int time = 0;
for (int col = 0; col < 4; col++)
{
hitObjects.Add(new Note { Column = col, StartTime = time, Samples = new List<HitSampleInfo>() });
time += 10;
}
beatmap.HitObjects = hitObjects.Cast<ManiaHitObject>().ToList();
beatmap.HitObjects = hitObjects.ToList();
// 规则:"12-|" → target0 from src1, target1 from src2, target2 cleared, target3 hold
var mod = new ManiaModCleanColumn();
mod.EnableCustomReorder.Value = true;
mod.CustomReorderColumn.Value = "12-|";
var mod = new ManiaModCleanColumn
{
EnableCustomReorder =
{
Value = true
},
CustomReorderColumn =
{
Value = "12-|"
}
};
mod.ApplyToBeatmap(beatmap);
@@ -139,12 +169,15 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
public void QuestionMarkOperator_DoesNotThrow_ProducesExpectedColumnCount()
{
// 源谱面 3 列,分别有 1、2、3 个 note
var beatmap = new ManiaBeatmap(new StageDefinition(3));
beatmap.Difficulty = new BeatmapDifficulty { CircleSize = 3 };
var beatmap = new ManiaBeatmap(new StageDefinition(3))
{
Difficulty = new BeatmapDifficulty { CircleSize = 3 }
};
var hitObjects = new List<ManiaHitObject>();
int time = 0;
int[] sourceCounts = { 1, 2, 3 };
for (int col = 0; col < sourceCounts.Length; col++)
{
for (int k = 0; k < sourceCounts[col]; k++)
@@ -154,11 +187,19 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
}
}
beatmap.HitObjects = hitObjects.Cast<ManiaHitObject>().ToList();
beatmap.HitObjects = hitObjects.ToList();
var mod = new ManiaModCleanColumn();
mod.EnableCustomReorder.Value = true;
mod.CustomReorderColumn.Value = "1?3?"; // includes two '?' positions
var mod = new ManiaModCleanColumn
{
EnableCustomReorder =
{
Value = true
},
CustomReorderColumn =
{
Value = "1?3?" // includes two '?' positions
}
};
// should not throw
Assert.DoesNotThrow(() => mod.ApplyToBeatmap(beatmap));

View File

@@ -31,9 +31,9 @@ namespace osu.Game.Rulesets.Mania.Tests
private ScoreInfo testScore;
private IBeatmap testBeatmap;
private const int RANDOM_SEED = 1234; // Fixed seed for consistent random data
private const int COLUMNS = 7; // 7k
private const int NOTES_PER_COLUMN = 50; // 50 notes per column
private const int random_seed = 1234; // Fixed seed for consistent random data
private const int columns = 7; // 7k
private const int notes_per_column = 50; // 50 notes per column
[SetUp]
public void SetUp()
@@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Mania.Tests
/// </summary>
private IBeatmap createTestBeatmap()
{
var beatmap = new ManiaBeatmap(new StageDefinition(COLUMNS))
var beatmap = new ManiaBeatmap(new StageDefinition(columns))
{
BeatmapInfo = new BeatmapInfo
{
@@ -137,12 +137,12 @@ namespace osu.Game.Rulesets.Mania.Tests
ControlPointInfo = new ControlPointInfo()
};
var random = new Random(RANDOM_SEED);
var random = new Random(random_seed);
// Create 50 notes per column
for (int column = 0; column < COLUMNS; column++)
for (int column = 0; column < columns; column++)
{
for (int i = 0; i < NOTES_PER_COLUMN; i++)
for (int i = 0; i < notes_per_column; i++)
{
// Use fixed seed random for note timing within each column
double timeOffset = random.NextDouble() * 500; // Random offset between 0-500ms for each note
@@ -168,7 +168,7 @@ namespace osu.Game.Rulesets.Mania.Tests
private ScoreInfo createTestScore(IBeatmap beatmap)
{
var hitEvents = new List<HitEvent>();
var random = new Random(RANDOM_SEED);
var random = new Random(random_seed);
// Initialize hit windows based on beatmap difficulty
var hitWindows = new ManiaHitWindows();
@@ -181,7 +181,7 @@ namespace osu.Game.Rulesets.Mania.Tests
// Normal distribution centered at 0ms with σ=20ms (symmetric around 0)
for (int i = 0; i < 200; i++)
{
double offset = GenerateNormalOffset(random, 0, 20);
double offset = generateNormalOffset(random, 0, 20);
// Clamp to [-40, 40] range
offset = Math.Max(-40, Math.Min(40, offset));
@@ -197,7 +197,7 @@ namespace osu.Game.Rulesets.Mania.Tests
for (int i = 0; i < 25; i++)
{
// Positive side [40, 100]
double offset = GenerateNormalOffset(random, 40, 30);
double offset = generateNormalOffset(random, 40, 30);
offset = Math.Max(40, Math.Min(100, offset));
HitResult result = hitWindows.ResultFor(offset);
@@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.Mania.Tests
for (int i = 0; i < 25; i++)
{
// Negative side [-100, -40]
double offset = GenerateNormalOffset(random, -40, 30);
double offset = generateNormalOffset(random, -40, 30);
offset = Math.Max(-100, Math.Min(-40, offset));
HitResult result = hitWindows.ResultFor(offset);
@@ -225,7 +225,7 @@ namespace osu.Game.Rulesets.Mania.Tests
for (int i = 0; i < 10; i++)
{
// Positive side [100, 150]
double offset = GenerateNormalOffset(random, 100, 25);
double offset = generateNormalOffset(random, 100, 25);
offset = Math.Max(100, Math.Min(150, offset));
HitResult result = hitWindows.ResultFor(offset);
@@ -238,7 +238,7 @@ namespace osu.Game.Rulesets.Mania.Tests
for (int i = 0; i < 10; i++)
{
// Negative side [-150, -100]
double offset = GenerateNormalOffset(random, -100, 25);
double offset = generateNormalOffset(random, -100, 25);
offset = Math.Max(-150, Math.Min(-100, offset));
HitResult result = hitWindows.ResultFor(offset);
@@ -253,7 +253,7 @@ namespace osu.Game.Rulesets.Mania.Tests
for (int i = 0; i < 5; i++)
{
// Positive side [150, 200]
double offset = GenerateNormalOffset(random, 150, 25);
double offset = generateNormalOffset(random, 150, 25);
offset = Math.Max(150, Math.Min(200, offset));
HitResult result = hitWindows.ResultFor(offset);
@@ -266,7 +266,7 @@ namespace osu.Game.Rulesets.Mania.Tests
for (int i = 0; i < 5; i++)
{
// Negative side [-200, -150]
double offset = GenerateNormalOffset(random, -150, 25);
double offset = generateNormalOffset(random, -150, 25);
offset = Math.Max(-200, Math.Min(-150, offset));
HitResult result = hitWindows.ResultFor(offset);
@@ -287,12 +287,12 @@ namespace osu.Game.Rulesets.Mania.Tests
switch (segment)
{
case 0: // [-40, 40]ms
offset = GenerateNormalOffset(random, 0, 20);
offset = generateNormalOffset(random, 0, 20);
offset = Math.Max(-40, Math.Min(40, offset));
break;
case 1: // [±40, ±100]ms
offset = GenerateNormalOffset(random, isNegative ? -40 : 40, 30);
offset = generateNormalOffset(random, isNegative ? -40 : 40, 30);
if (isNegative)
offset = Math.Max(-100, Math.Min(-40, offset));
else
@@ -300,7 +300,7 @@ namespace osu.Game.Rulesets.Mania.Tests
break;
case 2: // [±100, ±150]ms
offset = GenerateNormalOffset(random, isNegative ? -100 : 100, 25);
offset = generateNormalOffset(random, isNegative ? -100 : 100, 25);
if (isNegative)
offset = Math.Max(-150, Math.Min(-100, offset));
else
@@ -308,7 +308,7 @@ namespace osu.Game.Rulesets.Mania.Tests
break;
case 3: // [±150, ±200]ms
offset = GenerateNormalOffset(random, isNegative ? -150 : 150, 25);
offset = generateNormalOffset(random, isNegative ? -150 : 150, 25);
if (isNegative)
offset = Math.Max(-200, Math.Min(-150, offset));
else
@@ -338,7 +338,7 @@ namespace osu.Game.Rulesets.Mania.Tests
hitEvents.Add(new HitEvent(timeOffset, null, result, beatmap.HitObjects[i], null, null));
}
double accuracy = CalculateAccuracy(hitEvents);
double accuracy = calculateAccuracy(hitEvents);
return new ScoreInfo
{
@@ -355,7 +355,7 @@ namespace osu.Game.Rulesets.Mania.Tests
/// <summary>
/// Generate a random value from normal distribution using Box-Muller transform.
/// </summary>
private double GenerateNormalOffset(Random random, double mean, double stdDev)
private double generateNormalOffset(Random random, double mean, double stdDev)
{
double u1 = random.NextDouble();
double u2 = random.NextDouble();
@@ -366,7 +366,7 @@ namespace osu.Game.Rulesets.Mania.Tests
/// <summary>
/// Calculate accuracy based on hit event results.
/// </summary>
private double CalculateAccuracy(List<HitEvent> hitEvents)
private double calculateAccuracy(List<HitEvent> hitEvents)
{
double totalPoints = 0;
double maxPoints = 0;
@@ -414,17 +414,18 @@ namespace osu.Game.Rulesets.Mania.Tests
var hitWindows = new ManiaHitWindows();
hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty);
const double time_offset = 0;
foreach (var hitObject in beatmap.HitObjects)
{
// Perfect timing offset (0ms)
double timeOffset = 0;
// Calculate the correct hit result based on hit windows at perfect timing
HitResult result = hitWindows.ResultFor(timeOffset);
HitResult result = hitWindows.ResultFor(time_offset);
if (result == HitResult.None)
result = HitResult.Miss;
hitEvents.Add(new HitEvent(timeOffset, null, result, hitObject, null, null));
hitEvents.Add(new HitEvent(time_offset, null, result, hitObject, null, null));
}
return new ScoreInfo

View File

@@ -38,7 +38,6 @@ namespace osu.Game.Rulesets.Mania.LAsEZMania
}
// 公共属性定义本地化字符串,直接指定中文和英文
public static readonly EzLocalisableString Mania_Specific_Key = new EzLocalisableString("Mania特定中文");
// 添加更多属性...
public static readonly EzLocalisableString MANIA_SPECIFIC_KEY = new EzLocalisableString("Mania特定中文");
}
}

View File

@@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Mania.Mods.KrrConversion
// ---------------- 通用 LN/DP/N2N 方法 ----------------
// Beta 分布随机数生成
public static int GenerateRandom(double dBar, double uBar, double mBar, int pBar, Random r, LAsMods.EzOscillator? osc = null)
public static int GenerateRandom(double dBar, double uBar, double mBar, int pBar, Random r, EzOscillator? osc = null)
{
if (pBar <= 0) return (int)mBar;
@@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Mania.Mods.KrrConversion
}
// 百分比筛选
public static List<(int index, double start, int length)> MarkByPercentagePerGroup(List<(int index, double start, int length)> list, double percentage, Random r, LAsMods.EzOscillator osc)
public static List<(int index, double start, int length)> MarkByPercentagePerGroup(List<(int index, double start, int length)> list, double percentage, Random r, EzOscillator osc)
{
if (percentage >= 100) return list;
if (percentage <= 0) return new List<(int, double, int)>();

View File

@@ -84,10 +84,10 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
// 4、apply方法内部实现具体逻辑重复处理次数
// 5、最终统一清洗
public static void ProcessRollingWindowWithOscillator(ManiaBeatmap beatmap,
KeyPatternType patternType,
KeyPatternSettings psSettings,
IEzOscillator oscillator,
Action<List<ManiaHitObject>, ManiaBeatmap, double, double, KeyPatternSettings, Random, int> applyPattern)
KeyPatternType patternType,
KeyPatternSettings psSettings,
IEzOscillator oscillator,
Action<List<ManiaHitObject>, ManiaBeatmap, double, double, KeyPatternSettings, Random, int> applyPattern)
{
if (psSettings.Level <= 0)
return;
@@ -122,12 +122,12 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
for (long wi = 0; wi <= totalWindows; wi++)
{
double wstart = currentTime + wi * stepDuration;
double wend = wstart + windowDuration;
var ctx = new WindowContext(beatLength, wstart, windowDuration, stepDuration, 0, 0, beatmap.TotalColumns, 5.0);
double wStart = currentTime + wi * stepDuration;
double wEnd = wStart + windowDuration;
var ctx = new WindowContext(beatLength, wStart, windowDuration, stepDuration, 0, 0, beatmap.TotalColumns, 5.0);
bool skip = shouldSkipDenseWindow(patternType, objects, ctx, psSettings);
windowInfos.Add((wi, wstart, wend, skip));
windowInfos.Add((wi, wStart, wEnd, skip));
}
// 处理窗口:在需要时再计算 startIndex/endIndex 与构建 windowObjects以便 applyPattern 修改后可重建 objects
@@ -234,9 +234,9 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
}
internal static bool HasDenseBurstBetweenQuarterNotes(List<ManiaHitObject> windowObjects,
double beatLength,
int totalColumns,
KeyPatternSettings? psSettings = null)
double beatLength,
int totalColumns,
KeyPatternSettings psSettings)
{
double anchorInterval = beatLength;
if (anchorInterval <= 0)
@@ -291,10 +291,8 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
int countQuarter = 0;
int countOther = 0;
int fineThresholdDefault = 2;
int quarterDivDefault = 3;
int fineThreshold = psSettings?.FineCountThreshold ?? fineThresholdDefault;
int quarterDiv = psSettings?.QuarterLineDivisor ?? quarterDivDefault;
int fineThreshold = psSettings.FineCountThreshold;
int quarterDiv = psSettings.QuarterLineDivisor;
int mixedThreshold = Math.Max(fineThreshold, totalColumns / Math.Max(1, quarterDiv));
for (int i = start + 1; i < end; i++)
@@ -702,9 +700,9 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
}
private static bool shouldSkipDenseWindow(KeyPatternType patternType,
List<ManiaHitObject> objects,
WindowContext ctx,
KeyPatternSettings? psSettings)
List<ManiaHitObject> objects,
WindowContext ctx,
KeyPatternSettings? psSettings)
{
if (patternType == KeyPatternType.Delay || patternType == KeyPatternType.Dump)
return false;
@@ -961,7 +959,8 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
List<ManiaHitObject> windowObjects;
var pool = window_objects_pool.Value;
if (pool.Count > 0)
if (pool?.Count > 0)
{
windowObjects = pool.Pop();
windowObjects.Clear();
@@ -982,7 +981,7 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
var pool = window_objects_pool.Value;
// keep pool bounded to avoid unbounded memory usage
if (pool.Count < 128)
if (pool?.Count < 128)
{
list.Clear();
pool.Push(list);

View File

@@ -329,7 +329,7 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
return false;
}
private List<PatternShiftNote> ModifyNotesByDifficulty(List<PatternShiftNote> originalNotes, ManiaBeatmap beatmap, int targetColumns, int stars, Random rng)
private List<PatternShiftNote> modifyNotesByDifficulty(List<PatternShiftNote> originalNotes, ManiaBeatmap beatmap, int targetColumns, int stars, Random rng)
{
// Default behavior: stars==5 => minimal change. stars<5 remove notes; stars>5 add notes.
var notes = new List<PatternShiftNote>(originalNotes);
@@ -489,14 +489,6 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
return notes;
}
// audio-based regeneration removed; use ModifyNotesByDifficulty to adjust original notes
private static int MaxChordDefault(int targetColumns)
{
// heuristic: more keys allow slightly larger chords
return Math.Min(5, Math.Max(1, targetColumns / 2));
}
// In-place Cooley-Tukey FFT (radix-2)
private static void FFT(Complex[] buffer, bool inverse)
{
@@ -590,7 +582,7 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
}).OrderBy(n => n.StartTime).ThenBy(n => n.SourceColumn).ToList();
if (Regenerate.Value)
notes = ModifyNotesByDifficulty(notes, maniaBeatmap, targetColumns, RegenerateDifficulty.Value, rng);
notes = modifyNotesByDifficulty(notes, maniaBeatmap, targetColumns, RegenerateDifficulty.Value, rng);
var chords = buildChords(notes);
applyDelay(chords, maniaBeatmap.ControlPointInfo, DelayLevel.Value, rng);

View File

@@ -100,11 +100,11 @@ namespace osu.Game.Rulesets.Mania.Mods.LAsMods
return anchor < 0 ? 0 : anchor;
}
int countAtTime(double time)
{
var cols = ManiaKeyPatternHelp.GetColumnsAtTime(windowObjects, time, TIME_TOLERANCE);
return cols.Count;
}
// int countAtTime(double time)
// {
// var cols = ManiaKeyPatternHelp.GetColumnsAtTime(windowObjects, time, TIME_TOLERANCE);
// return cols.Count;
// }
foreach (var obj in windowObjects)
{

View File

@@ -88,7 +88,9 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
yield return ("Target Accuracy", $"{Accuracy.Value}%");
yield return ("Max Speed", $"{MaxSpeed.Value:0.##}x");
yield return ("Min Speed", $"{MinSpeed.Value:0.##}x");
if (AdjustPitch.Value) yield return ("Adjust Pitch", "On");
yield return ("Speed Change", $"{SpeedChange.Value:0.###}x");
}
}

View File

@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
public override bool ValidForFreestyleAsRequiredMod => false;
public readonly int[] DivideNumber = [2, 4, 8, 3, 6, 9, 5, 7, 12, 16, 48, 35, 64];
public readonly double ERROR = 2;
public readonly double Error = 2;
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
{
@@ -194,7 +194,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
continue;
}
originalLNObjects = ManiaModYuModHelper.Transform(rng, Mu1.Value, SigmaDouble.Value + SigmaInteger.Value, Divide1.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects,
originalLNObjects = ManiaModYuModHelper.Transform(rng, Mu1.Value, SigmaDouble.Value + SigmaInteger.Value, Divide1.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects,
column, Divide2.Value, Mu2.Value, Mu1DMu2.Value);
}

View File

@@ -4,6 +4,7 @@
using System;
using System.Linq;
using System.Threading;
using JetBrains.Annotations;
using osu.Framework.Bindables;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
@@ -113,6 +114,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
LNHoldNote.TailJudgementSwitch = TailJudgementSwitch.Value;
}
[UsedImplicitly]
private class NoLNNote : Note
{
public NoLNNote(Note note)
@@ -127,6 +129,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
}
[UsedImplicitly]
private class NoLNHeadNote : HeadNote
{
}

View File

@@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
{
double fullDuration = locations[i + 1].startTime - locations[i].startTime;
double beatLength = beatmap.ControlPointInfo.TimingPointAt(locations[i + 1].startTime).BeatLength;
double beatBPM = beatmap.ControlPointInfo.TimingPointAt(locations[i + 1].startTime).BPM;
// double beatBPM = beatmap.ControlPointInfo.TimingPointAt(locations[i + 1].startTime).BPM;
double timeDivide = beatLength / Divide.Value; //beatBPM / 60 * 100 / Divide.Value;
double duration = rng.Next(100) < LongShort.Value ? fullDuration - timeDivide : timeDivide;
bool flag = true; // Can be transformed to LN
@@ -120,13 +120,13 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
}
if (Math.Abs(locations[locations.Count - 1].startTime - locations[locations.Count - 1].endTime) <= 2 || rng.Next(100) >= Percentage.Value)
if (Math.Abs(locations[^1].startTime - locations[^1].endTime) <= 2 || rng.Next(100) >= Percentage.Value)
{
newColumnObjects.Add(new Note
{
Column = column.Key,
StartTime = locations[locations.Count - 1].startTime,
Samples = locations[locations.Count - 1].samples
StartTime = locations[^1].startTime,
Samples = locations[^1].samples
});
}
else
@@ -134,9 +134,9 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
newColumnObjects.Add(new HoldNote
{
Column = column.Key,
StartTime = locations[locations.Count - 1].startTime,
Duration = locations[locations.Count - 1].endTime - locations[locations.Count - 1].startTime,
NodeSamples = [locations[locations.Count - 1].samples, Array.Empty<HitSampleInfo>()]
StartTime = locations[^1].startTime,
Duration = locations[^1].endTime - locations[^1].startTime,
NodeSamples = [locations[^1].samples, Array.Empty<HitSampleInfo>()]
});
}

View File

@@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
public override bool ValidForMultiplayer => true;
public override bool ValidForFreestyleAsRequiredMod => false;
public readonly double ERROR = 1.5;
public readonly double Error = 1.5;
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
{
@@ -118,23 +118,23 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
double duration = locations[i].endTime - locations[i].startTime;
if (duration < timeDivide + ERROR && Len.Value)
if (duration < timeDivide + Error && Len.Value)
{
duration = easierDivide;
gap = locations[i + 1].startTime - (locations[i].startTime + duration);
if (gap < timeDivide + ERROR)
if (gap < timeDivide + Error)
{
duration = locations[i + 1].startTime - locations[i].startTime - easierDivide;
}
}
if (gap < timeDivide + ERROR && Gap.Value)
if (gap < timeDivide + Error && Gap.Value)
{
duration = locations[i + 1].startTime - locations[i].startTime - easierDivide;
}
if (duration < easierDivide - ERROR)
if (duration < easierDivide - Error)
{
duration = 0;
}

View File

@@ -10,9 +10,7 @@ using osu.Framework.Utils;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.LAsEzExtensions.Mods;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.LAsEZMania;
using osu.Game.Rulesets.Mania.LAsEzMania.Mods;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
@@ -31,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
public override bool Ranked => false;
public override bool ValidForMultiplayer => true;
public override bool ValidForFreestyleAsRequiredMod => false;
public readonly double ERROR = 2;
public readonly double Error = 2;
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
{
@@ -122,77 +120,77 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
case -1:
{
double mu = -1;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 1, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 1, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 0:
{
double mu = 1;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 100, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 100, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 1:
{
double mu = 11; //LN duration μ
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 2:
{
double mu = 22;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 3:
{
double mu = 33;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 4:
{
double mu = 44;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 5:
{
double mu = 55;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 6:
{
double mu = 66;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 7:
{
double mu = 77;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.85, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 8:
{
double mu = 88;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.9, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 0.9, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
case 9:
{
double mu = 99;
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 1, Divide.Value, Percentage.Value, ERROR, OriginalLN.Value, beatmap, newObjects, column);
originalLNObjects = ManiaModYuModHelper.Transform(rng, mu, 1, Divide.Value, Percentage.Value, Error, OriginalLN.Value, beatmap, newObjects, column);
}
break;
@@ -285,7 +283,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
return originalLNObjects;
}
public List<ManiaHitObject> TrueRandom(IBeatmap beatmap, List<ManiaHitObject> newObjects, Random Rng, IGrouping<int, ManiaHitObject> column)
public List<ManiaHitObject> TrueRandom(IBeatmap beatmap, List<ManiaHitObject> newObjects, Random rng, IGrouping<int, ManiaHitObject> column)
{
var locations = column.OfType<Note>().Select(n => (column: n.Column, startTime: n.StartTime, endTime: n.StartTime, samples: n.Samples))
.Concat(column.OfType<HoldNote>().SelectMany(h => new[]
@@ -306,7 +304,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
// Beat length at the end of the hold note.
// double beatLength = beatmap.ControlPointInfo.TimingPointAt(locations[i + 1].startTime).BeatLength;
double duration = Rng.Next((int)fullDuration) + Rng.NextDouble();
double duration = rng.Next((int)fullDuration) + rng.NextDouble();
while (duration > fullDuration)
duration--;
@@ -315,7 +313,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
newColumnObjects.AddNote(locations[i].samples, column.Key, locations[i].startTime, locations[i].endTime);
originalLNObjects.AddNote(locations[i].samples, column.Key, locations[i].startTime, locations[i].endTime);
}
else if (Rng.Next(100) < Percentage.Value)
else if (rng.Next(100) < Percentage.Value)
{
newColumnObjects.AddLNByDuration(locations[i].samples, column.Key, locations[i].startTime, duration);
}
@@ -333,7 +331,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
[Obsolete]
public void Invert(IBeatmap beatmap,
List<ManiaHitObject> newObjects,
Random Rng,
Random rng,
List<(int column, double startTime, IList<HitSampleInfo> samples, double endTime)> locations,
List<(double lastStartTime, double lastEndTime, bool lastLN, double thisStartTime, double thisEndTime, bool thisLN)> noteList,
List<(IList<HitSampleInfo> lastSample, IList<HitSampleInfo> thisSample)> sampleList,
@@ -361,7 +359,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
{
newObjects.AddNote(sampleList[column].lastSample, column, noteList[column].lastStartTime, noteList[column].lastEndTime);
}
else if (Rng.Next(100) < Percentage.Value && flag)
else if (rng.Next(100) < Percentage.Value && flag)
{
newObjects.AddLNByDuration(sampleList[column].lastSample, column, noteList[column].lastStartTime, duration);
}

View File

@@ -66,6 +66,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
get
{
yield return ("Divide", $"{Divide.Value}");
if (BPM.Value is null) yield return ("BPM", "Auto");
else yield return ("BPM", $"{BPM.Value}");
if (For14Jack.Value) yield return ("For 1/4 Jack", "On");

View File

@@ -14,7 +14,6 @@ using osu.Game.Configuration;
using osu.Game.LAsEzExtensions.Mods;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.LAsEZMania;
using osu.Game.Rulesets.Mania.LAsEzMania.Mods;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
@@ -318,9 +317,9 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
var lastLine = new List<(int column, double startTime, double endTime, IList<HitSampleInfo> samples)>();
var nextLine = new List<(int column, double startTime, double endTime, IList<HitSampleInfo> samples)>();
double? middleTime = null;
IList<HitSampleInfo>? samples = null;
int lastQuantity = 0, middleQuantity = 0, nextQuantity = 0;
double? middleTime;
IList<HitSampleInfo>? samples;
int lastQuantity = 0, middleQuantity = 0, nextQuantity;
int i = 0, skip = 0;
foreach (var timingPoint in beatmap.HitObjects.GroupBy(h => h.StartTime))
@@ -385,7 +384,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
if (compare == 1)
{
if (probability > 0 && (middleQuantity >= nextQuantity && middleQuantity >= lastQuantity || ignoreComparison))
if (probability > 0 && ((middleQuantity >= nextQuantity && middleQuantity >= lastQuantity) || ignoreComparison))
{
foreach (int column in columnWithNoNote)
{
@@ -417,7 +416,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
else if (compare == 2)
{
if (probability > 0 && (middleQuantity <= nextQuantity && middleQuantity <= lastQuantity || ignoreComparison))
if (probability > 0 && ((middleQuantity <= nextQuantity && middleQuantity <= lastQuantity) || ignoreComparison))
{
foreach (int column in columnWithNoNote)
{
@@ -433,7 +432,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
}
}
else if (probability < 0 && (middleQuantity <= nextQuantity && middleQuantity <= lastQuantity || ignoreComparison))
else if (probability < 0 && ((middleQuantity <= nextQuantity && middleQuantity <= lastQuantity) || ignoreComparison))
{
foreach (int column in columnWithNote)
{
@@ -517,7 +516,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
if (compare == 1)
{
if (probability > 0 && (middleQuantity >= nextQuantity && middleQuantity >= lastQuantity || ignoreComparison))
if (probability > 0 && ((middleQuantity >= nextQuantity && middleQuantity >= lastQuantity) || ignoreComparison))
{
foreach (int column in columnWithNoNote)
{
@@ -533,7 +532,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
}
}
else if (probability < 0 && (middleQuantity >= nextQuantity && middleQuantity >= lastQuantity || ignoreComparison))
else if (probability < 0 && ((middleQuantity >= nextQuantity && middleQuantity >= lastQuantity) || ignoreComparison))
{
foreach (int column in columnWithNote)
{
@@ -565,7 +564,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
}
}
else if (probability < 0 && (middleQuantity <= nextQuantity && middleQuantity <= lastQuantity || ignoreComparison))
else if (probability < 0 && ((middleQuantity <= nextQuantity && middleQuantity <= lastQuantity) || ignoreComparison))
{
foreach (int column in columnWithNote)
{
@@ -580,7 +579,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
}
skip:
skip:
if (skip > 0)
{
@@ -658,7 +657,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
}
}
else if (probability < 0 && (middleQuantity >= nextQuantity && middleQuantity >= lastQuantity || ignoreComparison))
else if (probability < 0 && ((middleQuantity >= nextQuantity && middleQuantity >= lastQuantity) || ignoreComparison))
{
foreach (int column in columnWithNote)
{
@@ -673,7 +672,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
else if (compare == 2)
{
if (probability > 0 && (middleQuantity <= nextQuantity && middleQuantity <= lastQuantity || ignoreComparison))
if (probability > 0 && ((middleQuantity <= nextQuantity && middleQuantity <= lastQuantity) || ignoreComparison))
{
foreach (int column in columnWithNoNote)
{
@@ -688,7 +687,7 @@ namespace osu.Game.Rulesets.Mania.Mods.YuLiangSSSMods
}
}
}
else if (probability < 0 && (middleQuantity <= nextQuantity && middleQuantity <= lastQuantity || ignoreComparison))
else if (probability < 0 && ((middleQuantity <= nextQuantity && middleQuantity <= lastQuantity) || ignoreComparison))
{
foreach (int column in columnWithNote)
{

View File

@@ -20,11 +20,6 @@ namespace osu.Game.Rulesets.Mania.Objects
/// </summary>
public bool UseHealthCapReduction { get; set; }
public PunishmentHoldNote()
{
// Mark this as a special punishment note
}
public override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;

View File

@@ -137,9 +137,9 @@ namespace osu.Game.Rulesets.Mania.Scoring
// Suppress extremely small floating-point changes which are noise
// and can cause issues (e.g. infinite loading) when treated as non-zero.
const double EPSILON = 1e-6;
const double epsilon = 1e-6;
if (Math.Abs(scaled) < EPSILON)
if (Math.Abs(scaled) < epsilon)
{
scaled = 0;
}

View File

@@ -205,14 +205,14 @@ namespace osu.Game.Rulesets.Mania.Scoring
private void setHitMode()
{
EzEnumHitMode HitMode = GlobalConfigStore.EzConfig?.Get<EzEnumHitMode>(Ez2Setting.HitMode) ?? EzEnumHitMode.Lazer;
EzEnumHitMode hitMode = GlobalConfigStore.EzConfig?.Get<EzEnumHitMode>(Ez2Setting.HitMode) ?? EzEnumHitMode.Lazer;
if (HitMode == EzEnumHitMode.Lazer)
if (hitMode == EzEnumHitMode.Lazer)
{
return;
}
switch (HitMode)
switch (hitMode)
{
case EzEnumHitMode.O2Jam:
modifyManiaHitRange(custom_helper.GetHitWindowsO2Jam(BPM));
@@ -225,7 +225,7 @@ namespace osu.Game.Rulesets.Mania.Scoring
case EzEnumHitMode.IIDX_HD:
case EzEnumHitMode.LR2_HD:
case EzEnumHitMode.Raja_NM:
modifyManiaHitRange(custom_helper.GetHitWindowsBMS(HitMode));
modifyManiaHitRange(custom_helper.GetHitWindowsBMS(hitMode));
break;
case EzEnumHitMode.Malody:

View File

@@ -180,6 +180,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Ez2
background.Colour = c.Darken(0.2f);
bottomIcon.Colour = c;
}
// apply current value immediately and subscribe to future changes via local bindable
applyAccent(accentColourLocal.Value);
accentColourLocal.BindValueChanged(e => applyAccent(e.NewValue), true);

View File

@@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Ez2
private IBindable<Color4> accentColour = null!;
private readonly Circle colouredBox;
private Drawable iconContainer = null!;
private readonly Drawable iconContainer;
public Ez2NotePiece()
{
@@ -102,8 +102,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Ez2
// NoteHeight = (float)config.Get<double>(ManiaRulesetSetting.ColumnWidth);
// specialFactor = (float)config.Get<double>(ManiaRulesetSetting.SpecialFactor);
if (iconContainer != null)
iconContainer.Size = new Vector2(DrawWidth / NoteHeight * 0.7f);
iconContainer.Size = new Vector2(DrawWidth / NoteHeight * 0.7f);
}
protected virtual Drawable CreateIcon() => new Container

View File

@@ -27,7 +27,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Ez2
public class ManiaEz2SkinTransformer : SkinTransformer
{
private readonly ManiaBeatmap beatmap;
private readonly Ez2ConfigManager ezSkinConfig;
private readonly IBindable<double> columnWidthBindable;
private readonly IBindable<double> specialFactorBindable;
private readonly IBindable<double> hitPosition;
@@ -43,12 +42,12 @@ namespace osu.Game.Rulesets.Mania.Skinning.Ez2
Logger.Log("!GlobalConfigStore.EzConfig Ez2Skin", LoggingTarget.Runtime, LogLevel.Important);
}
ezSkinConfig = GlobalConfigStore.EzConfig!;
// this.ezSkinSettings = ezSkinSettings ?? throw new ArgumentNullException(nameof(ezSkinSettings));
var ezSkinConfig1 = GlobalConfigStore.EzConfig!;
columnWidthBindable = ezSkinConfig.GetBindable<double>(Ez2Setting.ColumnWidth);
specialFactorBindable = ezSkinConfig.GetBindable<double>(Ez2Setting.SpecialFactor);
hitPosition = ezSkinConfig.GetBindable<double>(Ez2Setting.HitPosition);
// this.ezSkinSettings = ezSkinSettings ?? throw new ArgumentNullException(nameof(ezSkinSettings));
columnWidthBindable = ezSkinConfig1.GetBindable<double>(Ez2Setting.ColumnWidth);
specialFactorBindable = ezSkinConfig1.GetBindable<double>(Ez2Setting.SpecialFactor);
hitPosition = ezSkinConfig1.GetBindable<double>(Ez2Setting.HitPosition);
}
public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup)

View File

@@ -125,7 +125,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Ez2HUD
ColourAccent.BindValueChanged(_ => updateAccentColour(), true);
ColourGlow.BindValueChanged(_ => updateGlowColour(), true);
}
private void updateAccentColour()

View File

@@ -122,10 +122,5 @@ namespace osu.Game.Rulesets.Mania.Skinning.Ez2HUD
// (see: https://github.com/ppy/osu-framework/blob/fe2769171c6e26d1b6fdd6eb7ea8353162fe9065/osu.Framework/Graphics/Transforms/TransformBindable.cs#L21)
FinishTransforms(targetMember: $"{Current.GetHashCode()}.{nameof(Current.Value)}");
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
}
}
}

View File

@@ -137,7 +137,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Ez2HUD
private string fastTextLNString = string.Empty;
private string slowTextLNString = string.Empty;
private BindableNumber<float> gap = new BindableNumber<float>();
private readonly BindableNumber<float> gap = new BindableNumber<float>();
private (HitResult result, double length)[] hitWindows = null!;

View File

@@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.EzStylePro
if (animation == null)
OnDrawableChanged();
IsHitting.BindValueChanged(hitting =>
IsHitting.BindValueChanged(hitting =>
{
ClearTransforms();

View File

@@ -56,7 +56,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.EzStylePro
tailMaskHeight = Column.EzSkinInfo.HoldTailMaskHeight;
tailAlpha = Column.EzSkinInfo.HoldTailAlpha;
isHitting ??= holdNote.IsHolding;
isHitting.BindValueChanged(onIsHittingChanged, true);
// Column will notify notes about EzSkinInfo-driven size changes via NoteSizeChanged; avoid per-note BindValueChanged

View File

@@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.EzStylePro
private readonly IBindable<double> hitPositonBindable = new BindableDouble();
private readonly IBindable<double> columnWidth = new BindableDouble();
private readonly IBindable<string> noteSetName = new Bindable<string>();
// private readonly LayoutValue layout = new LayoutValue(Invalidation.DrawSize);
private Container sprite = null!;

View File

@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.EzStylePro
[Resolved]
protected EzLocalTextureFactory Factory { get; private set; } = null!;
protected readonly IBindable<Colour4> columnColorBindable = new Bindable<Colour4>();
protected readonly IBindable<Colour4> ColumnColorBindable = new Bindable<Colour4>();
protected readonly IBindable<string> NoteSetName = new Bindable<string>();
protected readonly IBindable<bool> EnabledColor = new Bindable<bool>();
protected readonly IBindable<Vector2> NoteSize = new Bindable<Vector2>();
@@ -126,6 +126,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.EzStylePro
{
lastNoteColorCached = false;
UpdateColor();
if (LineContainer?.Children != null)
{
foreach (var child in LineContainer.Children)

View File

@@ -64,8 +64,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.EzStylePro
public void UpdateTrackLineHeight()
{
if (separator != null)
separator.Height = (float)column.EzSkinInfo.NoteTrackLineHeight.Value;
separator.Height = (float)column.EzSkinInfo.NoteTrackLineHeight.Value;
}
protected override void LoadComplete()

View File

@@ -28,7 +28,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.EzStylePro
private readonly IBindable<double> columnWidthBindable;
private readonly IBindable<double> specialFactorBindable;
private readonly IBindable<double> hitPosition;
private readonly IBindable<double> virtualHitPosition;
//EzSkinSettings即使不用也不能删否则特殊列计算会出错
public ManiaEzStyleProSkinTransformer(ISkin skin, IBeatmap beatmap)
@@ -46,7 +45,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.EzStylePro
columnWidthBindable = ezSkinConfig.GetBindable<double>(Ez2Setting.ColumnWidth);
specialFactorBindable = ezSkinConfig.GetBindable<double>(Ez2Setting.SpecialFactor);
hitPosition = ezSkinConfig.GetBindable<double>(Ez2Setting.HitPosition);
virtualHitPosition = ezSkinConfig.GetBindable<double>(Ez2Setting.VisualHitPosition);
}
public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup)
@@ -160,7 +158,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.EzStylePro
judgementPiece.Y = 100;
}
var O2PillBar = container.OfType<O2PillBar>().FirstOrDefault();
var o2PillBar = container.OfType<O2PillBar>().FirstOrDefault();
})
{
new EzComComboSprite(),

View File

@@ -29,7 +29,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.SbI
private readonly IBindable<double> columnWidthBindable;
private readonly IBindable<double> specialFactorBindable;
private readonly IBindable<double> hitPosition;
private readonly IBindable<double> virtualHitPosition;
public ManiaSbISkinTransformer(ISkin skin, IBeatmap beatmap)
: base(skin)
@@ -45,7 +44,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.SbI
columnWidthBindable = ezSkinConfig.GetBindable<double>(Ez2Setting.ColumnWidth);
specialFactorBindable = ezSkinConfig.GetBindable<double>(Ez2Setting.SpecialFactor);
hitPosition = ezSkinConfig.GetBindable<double>(Ez2Setting.HitPosition);
virtualHitPosition = ezSkinConfig.GetBindable<double>(Ez2Setting.VisualHitPosition);
}
public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup)

View File

@@ -49,9 +49,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.SbI
},
};
}
// colour is driven by ez column colours via EzNoteBase
}
protected override void LoadComplete()

View File

@@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.Editing
// Test that the screen loads without errors
AddStep("load screen", () => { });
AddAssert("screen is not null", () => ezSkinEditorScreen != null);
AddAssert("screen is EzSkinEditorScreen", () => ezSkinEditorScreen is EzSkinEditorScreen);
AddAssert("screen is EzSkinEditorScreen", () => ezSkinEditorScreen != null);
}
// Removed TestPushScreen as Stack is not accessible in this context

View File

@@ -19,7 +19,7 @@ namespace osu.Game.LAsEzExtensions.Audio
{
private const string log_prefix = "[LAsEz/DuplicateVirtualTrack]";
private void Log(string message)
private void log(string message)
{
try
{
@@ -100,7 +100,7 @@ namespace osu.Game.LAsEzExtensions.Audio
}
catch (Exception ex)
{
Log($"error removing previous mute adjustment: {ex}");
log($"error removing previous mute adjustment: {ex}");
}
beatmapTrackMuteAdjustment = new BindableDouble(0);
@@ -109,7 +109,7 @@ namespace osu.Game.LAsEzExtensions.Audio
try
{
Log(
log(
$"StartPreview overrides: StartTime={overrides.StartTime} Duration={overrides.Duration} LoopCount={overrides.LoopCount} LoopInterval={overrides.LoopInterval} ForceLooping={overrides.ForceLooping}");
}
catch { }
@@ -131,7 +131,7 @@ namespace osu.Game.LAsEzExtensions.Audio
try
{
Log(
log(
$"StartPreview overrides: StartTime={overrides.StartTime} Duration={overrides.Duration} LoopCount={overrides.LoopCount} LoopInterval={overrides.LoopInterval} ForceLooping={overrides.ForceLooping}");
}
catch { }
@@ -197,7 +197,7 @@ namespace osu.Game.LAsEzExtensions.Audio
try
{
activeCandidateTrack.Stop();
Log("paused candidate due to gameplayClock.IsRunning=false");
log("paused candidate due to gameplayClock.IsRunning=false");
}
catch { }
@@ -211,7 +211,7 @@ namespace osu.Game.LAsEzExtensions.Audio
{
// Resume playback from current time.
activeCandidateTrack.Start();
Log("resumed candidate due to gameplayClock.IsRunning=true");
log("resumed candidate due to gameplayClock.IsRunning=true");
}
catch { }
@@ -231,7 +231,7 @@ namespace osu.Game.LAsEzExtensions.Audio
if (now + epsilon >= sliceEnd)
{
Log($"loopChecker triggered now={now} sliceEnd={sliceEnd} loopsRemaining={loopsRemaining}");
log($"loopChecker triggered now={now} sliceEnd={sliceEnd} loopsRemaining={loopsRemaining}");
if (loopsRemaining <= 1)
{
@@ -280,7 +280,7 @@ namespace osu.Game.LAsEzExtensions.Audio
}
catch (Exception ex)
{
Log($"delayed restart failed: {ex}");
log($"delayed restart failed: {ex}");
}
}, delayMs);
}
@@ -290,6 +290,7 @@ namespace osu.Game.LAsEzExtensions.Audio
{
// 避免对beatmap.Track进行Seek因为那会影响主游戏音频
bool isUsingBeatmapTrack = pendingBeatmap?.Track != null && ReferenceEquals(activeCandidateTrack, pendingBeatmap.Track);
if (!isUsingBeatmapTrack)
{
activeCandidateTrack.Seek(sliceStart);
@@ -347,7 +348,7 @@ namespace osu.Game.LAsEzExtensions.Audio
}
catch (Exception ex)
{
Log($"failed to start candidate playback: {ex}");
log($"failed to start candidate playback: {ex}");
}
}
@@ -400,10 +401,11 @@ namespace osu.Game.LAsEzExtensions.Audio
{
// 避免对beatmap.Track进行Seek因为那会影响主游戏音频
bool isUsingBeatmapTrack = pendingBeatmap?.Track != null && ReferenceEquals(activeCandidateTrack, pendingBeatmap.Track);
if (!isUsingBeatmapTrack)
{
activeCandidateTrack.Seek(sliceStart);
Log($"seeked candidate to sliceStart on resume ({sliceStart})");
log($"seeked candidate to sliceStart on resume ({sliceStart})");
}
}
}
@@ -411,7 +413,7 @@ namespace osu.Game.LAsEzExtensions.Audio
}
activeCandidateTrack.Start();
Log("resumed candidate via IsPaused=false");
log("resumed candidate via IsPaused=false");
}
catch { }
@@ -423,7 +425,7 @@ namespace osu.Game.LAsEzExtensions.Audio
}
catch (Exception ex)
{
Log($"error handling IsPaused change: {ex}");
log($"error handling IsPaused change: {ex}");
}
};
@@ -507,25 +509,26 @@ namespace osu.Game.LAsEzExtensions.Audio
{
// 避免对beatmap.Track进行Seek因为那会影响主游戏音频
bool isUsingBeatmapTrack = pendingBeatmap?.Track != null && ReferenceEquals(activeCandidateTrack, pendingBeatmap.Track);
if (!isUsingBeatmapTrack)
{
activeCandidateTrack.Seek(sliceStart);
Log($"seamless seek to {sliceStart}");
log($"seamless seek to {sliceStart}");
}
}
catch (Exception ex) { Log($"seamless seek failed: {ex}"); }
catch (Exception ex) { log($"seamless seek failed: {ex}"); }
}
}
}
catch (Exception ex)
{
Log($"loopChecker error: {ex}");
log($"loopChecker error: {ex}");
}
}, 30, true);
}
catch (Exception ex)
{
Log($"ensureLoopCheckerRunning failed: {ex}");
log($"ensureLoopCheckerRunning failed: {ex}");
}
}
@@ -586,12 +589,12 @@ namespace osu.Game.LAsEzExtensions.Audio
}
catch (Exception ex)
{
Log($"ensure length failed for {candidateNames[i]}: {ex.Message}");
log($"ensure length failed for {candidateNames[i]}: {ex.Message}");
}
if (t.Length > 0)
{
Log($"selected {candidateNames[i]} (length={t.Length})");
log($"selected {candidateNames[i]} (length={t.Length})");
if (gameplayClockContainer != null)
t.BindAdjustments(gameplayClockContainer.AdjustmentsFromMods);
if (gameplayClockContainer is MasterGameplayClockContainer master)
@@ -609,11 +612,11 @@ namespace osu.Game.LAsEzExtensions.Audio
// Seek to desired candidate start time if provided, otherwise to 0.
double seekTarget = desiredCandidateStartTime ?? 0;
t.Seek(seekTarget);
Log($"prepared independent candidate track (hash={t.GetHashCode()}) stopped and seeked to {seekTarget}.");
log($"prepared independent candidate track (hash={t.GetHashCode()}) stopped and seeked to {seekTarget}.");
}
catch (Exception ex)
{
Log($"failed to prepare candidate track: {ex}");
log($"failed to prepare candidate track: {ex}");
}
}
@@ -628,7 +631,7 @@ namespace osu.Game.LAsEzExtensions.Audio
var t = candidates[i];
if (t == null) continue;
Log($"fallback to {candidateNames[i]} (length={t.Length})");
log($"fallback to {candidateNames[i]} (length={t.Length})");
if (gameplayClockContainer != null)
t.BindAdjustments(gameplayClockContainer.AdjustmentsFromMods);
if (gameplayClockContainer is MasterGameplayClockContainer master)
@@ -643,11 +646,11 @@ namespace osu.Game.LAsEzExtensions.Audio
t.Stop();
double seekTarget = desiredCandidateStartTime ?? 0;
t.Seek(seekTarget);
Log($"prepared fallback candidate track (hash={t.GetHashCode()}) stopped and seeked to {seekTarget}.");
log($"prepared fallback candidate track (hash={t.GetHashCode()}) stopped and seeked to {seekTarget}.");
}
catch (Exception ex)
{
Log($"failed to prepare fallback candidate track: {ex}");
log($"failed to prepare fallback candidate track: {ex}");
}
}
@@ -655,7 +658,7 @@ namespace osu.Game.LAsEzExtensions.Audio
return t;
}
Log("no candidate found, using beatmap.Track");
log("no candidate found, using beatmap.Track");
return null;
}
@@ -672,7 +675,7 @@ namespace osu.Game.LAsEzExtensions.Audio
}
catch (Exception ex)
{
Log($"failed to stop active candidate track on StopPreview: {ex}");
log($"failed to stop active candidate track on StopPreview: {ex}");
}
// If we applied a candidate mute adjustment during a loop delay, remove it now.
@@ -696,7 +699,7 @@ namespace osu.Game.LAsEzExtensions.Audio
try { activeCandidateTrack.Looping = prevCandidateLooping.Value; }
catch { }
Log($"restored candidate track.Looping to {prevCandidateLooping.Value}");
log($"restored candidate track.Looping to {prevCandidateLooping.Value}");
}
}
catch { }
@@ -722,7 +725,7 @@ namespace osu.Game.LAsEzExtensions.Audio
{
try
{
Log(
log(
$"removing mute adjustment from original track (hash={mutedOriginalTrack.GetHashCode()}) on StopPreview. pre: vol={mutedOriginalTrack.Volume.Value:F3} aggr={mutedOriginalTrack.AggregateVolume.Value:F3}");
}
catch { }
@@ -733,19 +736,19 @@ namespace osu.Game.LAsEzExtensions.Audio
try
{
Log($"removed mute adjustment on StopPreview. post: vol={mutedOriginalTrack.Volume.Value:F3} aggr={mutedOriginalTrack.AggregateVolume.Value:F3}");
log($"removed mute adjustment on StopPreview. post: vol={mutedOriginalTrack.Volume.Value:F3} aggr={mutedOriginalTrack.AggregateVolume.Value:F3}");
}
catch { }
}
catch (Exception ex)
{
Log($"failed to remove mute adjustment on StopPreview: {ex}");
log($"failed to remove mute adjustment on StopPreview: {ex}");
}
}
}
catch (Exception ex)
{
Log($"failed to remove mute adjustment on StopPreview: {ex}");
log($"failed to remove mute adjustment on StopPreview: {ex}");
}
beatmapTrackMuteAdjustment = null;

View File

@@ -33,7 +33,7 @@ namespace osu.Game.LAsEzExtensions.Audio
private ScoreProcessor? scoreProcessor;
private EzLatencyManager latencyManager;
private readonly EzLatencyManager latencyManager;
private Bindable<bool>? inputAudioLatencyConfigBindable;
private Action<ValueChangedEvent<bool>>? inputAudioLatencyConfigHandler;
@@ -53,7 +53,7 @@ namespace osu.Game.LAsEzExtensions.Audio
public void Initialize(ScoreProcessor processor)
{
Logger.Log($"InputAudioLatencyTracker.Initialize called", LoggingTarget.Runtime, LogLevel.Debug);
Logger.Log("InputAudioLatencyTracker.Initialize called", LoggingTarget.Runtime, LogLevel.Debug);
scoreProcessor = processor;
// 将 Ez2Setting 的启用状态绑定到 EzLatencyManager
@@ -84,7 +84,7 @@ namespace osu.Game.LAsEzExtensions.Audio
started = true;
Logger.Log($"InputAudioLatencyTracker.Start called", LoggingTarget.Runtime, LogLevel.Debug);
Logger.Log("InputAudioLatencyTracker.Start called", LoggingTarget.Runtime, LogLevel.Debug);
if (scoreProcessor != null)
scoreProcessor.NewJudgement += OnNewJudgement;
@@ -143,7 +143,7 @@ namespace osu.Game.LAsEzExtensions.Audio
if (!stats.HasData)
{
Logger.Log($"[EzOsuLatency] No latency data available for analysis", LoggingTarget.Runtime, LogLevel.Debug);
Logger.Log("[EzOsuLatency] No latency data available for analysis", LoggingTarget.Runtime, LogLevel.Debug);
return;
}
@@ -155,14 +155,11 @@ namespace osu.Game.LAsEzExtensions.Audio
Logger.Log($"[EzOsuLatency] Latency Analysis: \n{message2}", LoggingTarget.Runtime, LogLevel.Important);
// 显示通知
if (notificationOverlay != null)
notificationOverlay?.Post(new SimpleNotification
{
notificationOverlay.Post(new SimpleNotification
{
Text = $"Latency analysis complete!\nInput→Judge: {stats.AvgInputToJudge:F1}ms\nInput→Audio: {stats.AvgInputToPlayback:F1}ms\nAudio→Judge: {stats.AvgPlaybackToJudge:F1}ms\nRecords: {stats.RecordCount}",
Icon = FontAwesome.Solid.ChartLine,
});
}
Text = $"Latency analysis complete!\nInput→Judge: {stats.AvgInputToJudge:F1}ms\nInput→Audio: {stats.AvgInputToPlayback:F1}ms\nAudio→Judge: {stats.AvgPlaybackToJudge:F1}ms\nRecords: {stats.RecordCount}",
Icon = FontAwesome.Solid.ChartLine,
});
}
private void OnNewJudgement(JudgementResult result)
@@ -191,11 +188,8 @@ namespace osu.Game.LAsEzExtensions.Audio
Stop();
// 解绑事件
if (latencyManager != null)
{
latencyManager.OnNewRecord -= OnLatencyRecordGenerated;
latencyManager.Dispose();
}
latencyManager.OnNewRecord -= OnLatencyRecordGenerated;
latencyManager.Dispose();
if (inputAudioLatencyConfigBindable != null && inputAudioLatencyConfigHandler != null)
inputAudioLatencyConfigBindable.ValueChanged -= inputAudioLatencyConfigHandler;

View File

@@ -70,7 +70,6 @@ namespace osu.Game.LAsEzExtensions.Configuration
SetDefault(Ez2Setting.ColumnWidth, 60, 5, 400.0, 1.0);
SetDefault(Ez2Setting.SpecialFactor, 1.2, 0.5, 2.0, 0.1);
SetDefault(Ez2Setting.HitPosition, DefaultHitPosition, 0, 500, 1.0);
SetDefault(Ez2Setting.VisualHitPosition, 0.0, -100, 100, 1.0);
SetDefault(Ez2Setting.HitTargetFloatFixed, 6, 0, 10, 0.1);
SetDefault(Ez2Setting.HitTargetAlpha, 0.6, 0, 1, 0.01);
@@ -455,7 +454,6 @@ namespace osu.Game.LAsEzExtensions.Configuration
HitPosition,
HitTargetFloatFixed,
HitTargetAlpha,
VisualHitPosition,
NoteHeightScaleToWidth,
NoteTrackLineHeight,
NoteSetName,

View File

@@ -59,7 +59,6 @@ namespace osu.Game.LAsEzExtensions.Configuration
SpecialFactorBindable.BindTo(config.GetBindable<double>(Ez2Setting.SpecialFactor));
HitPositionBindable.BindTo(config.GetBindable<double>(Ez2Setting.HitPosition));
VisualHitPositionBindable.BindTo(config.GetBindable<double>(Ez2Setting.VisualHitPosition));
NoteHeightScaleToWidthBindable.BindTo(config.GetBindable<double>(Ez2Setting.NoteHeightScaleToWidth));
NoteTrackLineHeightBindable.BindTo(config.GetBindable<double>(Ez2Setting.NoteTrackLineHeight));

View File

@@ -110,6 +110,7 @@ namespace osu.Game.LAsEzExtensions
void scheduleTextureRefresh()
{
if (textureRefreshScheduled) return;
textureRefreshScheduled = true;
Schedule(() =>
{
@@ -515,11 +516,19 @@ namespace osu.Game.LAsEzExtensions
catch
{
}
// 只清理实例级别的缓存,全局缓存留给 ClearGlobalCache 处理
foreach (var loader in loaderStoreCache.Values)
loader.Dispose();
loaderStoreCache.Clear();
// 只清理实例级别的缓存,全局缓存留给 ClearGlobalCache 处理
lock (loaderStoreCache)
{
foreach (var loader in loaderStoreCache.Values)
loader.Dispose();
}
lock (loaderStoreCache)
{
loaderStoreCache.Clear();
}
note_ratio_cache.Clear();
}

View File

@@ -21,7 +21,7 @@ namespace osu.Game.LAsEzExtensions.Mods
ApplyLoopToBeatmapStatic(beatmap, LoopCount.Value, cutTimeStart, cutTimeEnd, BreakQuarter.Value, Seed.Value);
}
public static void ApplyLoopToBeatmapStatic(IBeatmap beatmap, int loopCount, double cutTimeStart, double cutTimeEnd, int breakQuarter, int? seed = null)
public static void ApplyLoopToBeatmapStatic(IBeatmap? beatmap, int loopCount, double cutTimeStart, double cutTimeEnd, int breakQuarter, int? seed = null)
{
if (beatmap == null) return;
@@ -60,8 +60,6 @@ namespace osu.Game.LAsEzExtensions.Mods
var newPart = new List<HitObject>();
var rng = seed.HasValue ? new Random(seed.Value) : new Random();
double length = cutTimeEnd - cutTimeStart;
for (int timeIndex = 0; timeIndex < loopCount; timeIndex++)

View File

@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Reflection;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -17,7 +16,6 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osu.Game.Overlays.Dialog;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
@@ -368,13 +366,6 @@ namespace osu.Game.LAsEzExtensions.Screens
// 作为 overlay这里不应 Push/Present gameplay。
}
protected override void Update()
{
base.Update();
// Overlay 不需要更新屏幕大小
}
private partial class ApplySettingsButton : OsuButton
{
[BackgroundDependencyLoader]

View File

@@ -39,11 +39,5 @@ namespace osu.Game.Screens.Play.HUD.EzHealthDisplay
Content.Add(texture);
}
}
protected override void Update()
{
base.Update();
// Implement health update logic here
}
}
}

View File

@@ -795,14 +795,14 @@ namespace osu.Game.Screens.SelectV2
private ScheduledDelegate? loadingDebounce;
// Lightweight instrumentation for investigating filter performance regressions.
private double lastFilterMs;
private int lastFilterItems;
private int lastFilterPanels;
private int filterRuns;
public double LastFilterMs => lastFilterMs;
public int LastFilterItems => lastFilterItems;
public int LastFilterPanels => lastFilterPanels;
public double LastFilterMs { get; private set; }
public int LastFilterItems { get; private set; }
public int LastFilterPanels { get; private set; }
public int FilterRuns => filterRuns;
public void Filter(FilterCriteria criteria, bool showLoadingImmediately = false)
@@ -829,11 +829,11 @@ namespace osu.Game.Screens.SelectV2
try
{
sw.Stop();
lastFilterMs = sw.Elapsed.TotalMilliseconds;
LastFilterMs = sw.Elapsed.TotalMilliseconds;
var items = GetCarouselItems();
lastFilterItems = items?.Count ?? 0;
lastFilterPanels = Scroll.Panels.Count;
LastFilterItems = items?.Count ?? 0;
LastFilterPanels = Scroll.Panels.Count;
}
finally
{

View File

@@ -682,7 +682,7 @@ namespace osu.Game.Screens.SelectV2
}
}
#endregion
#endregion
}
/// <summary>