mirror of
https://github.com/ppy/osu.git
synced 2024-09-21 16:07:24 +08:00
Merge branch 'master' into results-screen-component-metrics
This commit is contained in:
commit
d5912165e9
@ -26,6 +26,8 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.Replays.Types;
|
using osu.Game.Rulesets.Replays.Types;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Ranking.Statistics;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch
|
namespace osu.Game.Rulesets.Catch
|
||||||
@ -218,5 +220,17 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
public override HitObjectComposer CreateHitObjectComposer() => new CatchHitObjectComposer(this);
|
public override HitObjectComposer CreateHitObjectComposer() => new CatchHitObjectComposer(this);
|
||||||
|
|
||||||
public override IBeatmapVerifier CreateBeatmapVerifier() => new CatchBeatmapVerifier();
|
public override IBeatmapVerifier CreateBeatmapVerifier() => new CatchBeatmapVerifier();
|
||||||
|
|
||||||
|
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,7 +412,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = 250
|
Height = 250
|
||||||
}, true),
|
}, true),
|
||||||
new StatisticItem(string.Empty, () => new SimpleStatisticTable(2, new SimpleStatisticItem[]
|
new StatisticItem("Statistics", () => new SimpleStatisticTable(2, new SimpleStatisticItem[]
|
||||||
{
|
{
|
||||||
new AverageHitError(score.HitEvents),
|
new AverageHitError(score.HitEvents),
|
||||||
new UnstableRate(score.HitEvents)
|
new UnstableRate(score.HitEvents)
|
||||||
|
@ -319,7 +319,7 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = 250
|
Height = 250
|
||||||
}, true),
|
}, true),
|
||||||
new StatisticItem(string.Empty, () => new SimpleStatisticTable(2, new SimpleStatisticItem[]
|
new StatisticItem("Statistics", () => new SimpleStatisticTable(2, new SimpleStatisticItem[]
|
||||||
{
|
{
|
||||||
new AverageHitError(timedHitEvents),
|
new AverageHitError(timedHitEvents),
|
||||||
new UnstableRate(timedHitEvents)
|
new UnstableRate(timedHitEvents)
|
||||||
|
@ -114,5 +114,75 @@ namespace osu.Game.Rulesets.Taiko.Tests.Judgements
|
|||||||
|
|
||||||
AddAssert("all tick offsets are 0", () => JudgementResults.Where(r => r.HitObject is SwellTick).All(r => r.TimeOffset == 0));
|
AddAssert("all tick offsets are 0", () => JudgementResults.Where(r => r.HitObject is SwellTick).All(r => r.TimeOffset == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ensure input is correctly sent to subsequent hits if a swell is fully completed.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestHitSwellThenHitHit()
|
||||||
|
{
|
||||||
|
const double swell_time = 1000;
|
||||||
|
const double hit_time = 1150;
|
||||||
|
|
||||||
|
Swell swell = new Swell
|
||||||
|
{
|
||||||
|
StartTime = swell_time,
|
||||||
|
Duration = 100,
|
||||||
|
RequiredHits = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
Hit hit = new Hit
|
||||||
|
{
|
||||||
|
StartTime = hit_time
|
||||||
|
};
|
||||||
|
|
||||||
|
List<ReplayFrame> frames = new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new TaikoReplayFrame(0),
|
||||||
|
new TaikoReplayFrame(swell_time, TaikoAction.LeftRim),
|
||||||
|
new TaikoReplayFrame(hit_time, TaikoAction.RightCentre),
|
||||||
|
};
|
||||||
|
|
||||||
|
PerformTest(frames, CreateBeatmap(swell, hit));
|
||||||
|
|
||||||
|
AssertJudgementCount(3);
|
||||||
|
|
||||||
|
AssertResult<SwellTick>(0, HitResult.IgnoreHit);
|
||||||
|
AssertResult<Swell>(0, HitResult.LargeBonus);
|
||||||
|
AssertResult<Hit>(0, HitResult.Great);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMissSwellThenHitHit()
|
||||||
|
{
|
||||||
|
const double swell_time = 1000;
|
||||||
|
const double hit_time = 1150;
|
||||||
|
|
||||||
|
Swell swell = new Swell
|
||||||
|
{
|
||||||
|
StartTime = swell_time,
|
||||||
|
Duration = 100,
|
||||||
|
RequiredHits = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
Hit hit = new Hit
|
||||||
|
{
|
||||||
|
StartTime = hit_time
|
||||||
|
};
|
||||||
|
|
||||||
|
List<ReplayFrame> frames = new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new TaikoReplayFrame(0),
|
||||||
|
new TaikoReplayFrame(hit_time, TaikoAction.RightCentre),
|
||||||
|
};
|
||||||
|
|
||||||
|
PerformTest(frames, CreateBeatmap(swell, hit));
|
||||||
|
|
||||||
|
AssertJudgementCount(3);
|
||||||
|
|
||||||
|
AssertResult<SwellTick>(0, HitResult.IgnoreMiss);
|
||||||
|
AssertResult<Swell>(0, HitResult.IgnoreMiss);
|
||||||
|
AssertResult<Hit>(0, HitResult.Great);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,6 +276,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
if (Time.Current < HitObject.StartTime)
|
if (Time.Current < HitObject.StartTime)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (AllJudged)
|
||||||
|
return false;
|
||||||
|
|
||||||
bool isCentre = e.Action == TaikoAction.LeftCentre || e.Action == TaikoAction.RightCentre;
|
bool isCentre = e.Action == TaikoAction.LeftCentre || e.Action == TaikoAction.RightCentre;
|
||||||
|
|
||||||
// Ensure alternating centre and rim hits
|
// Ensure alternating centre and rim hits
|
||||||
|
@ -256,7 +256,7 @@ namespace osu.Game.Rulesets.Taiko
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = 250
|
Height = 250
|
||||||
}, true),
|
}, true),
|
||||||
new StatisticItem(string.Empty, () => new SimpleStatisticTable(3, new SimpleStatisticItem[]
|
new StatisticItem("Statistics", () => new SimpleStatisticTable(3, new SimpleStatisticItem[]
|
||||||
{
|
{
|
||||||
new AverageHitError(timedHitEvents),
|
new AverageHitError(timedHitEvents),
|
||||||
new UnstableRate(timedHitEvents)
|
new UnstableRate(timedHitEvents)
|
||||||
|
@ -69,6 +69,8 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int onlineScoreID = 1;
|
||||||
|
|
||||||
[TestCase(1, ScoreRank.X)]
|
[TestCase(1, ScoreRank.X)]
|
||||||
[TestCase(0.9999, ScoreRank.S)]
|
[TestCase(0.9999, ScoreRank.S)]
|
||||||
[TestCase(0.975, ScoreRank.S)]
|
[TestCase(0.975, ScoreRank.S)]
|
||||||
@ -81,14 +83,17 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
{
|
{
|
||||||
TestResultsScreen screen = null;
|
TestResultsScreen screen = null;
|
||||||
|
|
||||||
var score = TestResources.CreateTestScoreInfo();
|
loadResultsScreen(() =>
|
||||||
|
{
|
||||||
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
|
||||||
score.OnlineID = 1234;
|
score.OnlineID = onlineScoreID++;
|
||||||
score.HitEvents = TestSceneStatisticsPanel.CreatePositionDistributedHitEvents();
|
score.HitEvents = TestSceneStatisticsPanel.CreatePositionDistributedHitEvents();
|
||||||
score.Accuracy = accuracy;
|
score.Accuracy = accuracy;
|
||||||
score.Rank = rank;
|
score.Rank = rank;
|
||||||
|
|
||||||
loadResultsScreen(() => screen = createResultsScreen(score));
|
return screen = createResultsScreen(score);
|
||||||
|
});
|
||||||
AddUntilStep("wait for loaded", () => screen.IsLoaded);
|
AddUntilStep("wait for loaded", () => screen.IsLoaded);
|
||||||
AddAssert("retry overlay present", () => screen.RetryOverlay != null);
|
AddAssert("retry overlay present", () => screen.RetryOverlay != null);
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Extensions.ObjectExtensions;
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Graphics.Cursor;
|
using osu.Game.Graphics.Cursor;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics.UserInterfaceV2;
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
@ -304,11 +304,8 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("preset is not changed", () => panel.Preset.Value.Name == presetName);
|
AddAssert("preset is not changed", () => panel.Preset.Value.Name == presetName);
|
||||||
AddUntilStep("popover is unchanged", () => this.ChildrenOfType<OsuPopover>().FirstOrDefault() == popover);
|
AddUntilStep("popover is unchanged", () => this.ChildrenOfType<OsuPopover>().FirstOrDefault() == popover);
|
||||||
AddStep("edit preset name", () => popover.ChildrenOfType<LabelledTextBox>().First().Current.Value = "something new");
|
AddStep("edit preset name", () => popover.ChildrenOfType<LabelledTextBox>().First().Current.Value = "something new");
|
||||||
AddStep("attempt preset edit", () =>
|
AddStep("commit changes to textbox", () => InputManager.Key(Key.Enter));
|
||||||
{
|
AddStep("attempt preset edit via select binding", () => InputManager.Key(Key.Enter));
|
||||||
InputManager.MoveMouseTo(popover.ChildrenOfType<ShearedButton>().ElementAt(1));
|
|
||||||
InputManager.Click(MouseButton.Left);
|
|
||||||
});
|
|
||||||
AddUntilStep("popover closed", () => !this.ChildrenOfType<OsuPopover>().Any());
|
AddUntilStep("popover closed", () => !this.ChildrenOfType<OsuPopover>().Any());
|
||||||
AddAssert("preset is changed", () => panel.Preset.Value.Name != presetName);
|
AddAssert("preset is changed", () => panel.Preset.Value.Name != presetName);
|
||||||
}
|
}
|
||||||
|
@ -542,7 +542,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
AddStep("clear search", () => modSelectOverlay.SearchTerm = string.Empty);
|
AddStep("clear search", () => modSelectOverlay.SearchTerm = string.Empty);
|
||||||
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
||||||
AddAssert("mod select hidden", () => modSelectOverlay.State.Value == Visibility.Hidden);
|
AddAssert("mod select still visible", () => modSelectOverlay.State.Value == Visibility.Visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -431,8 +431,9 @@ namespace osu.Game.Beatmaps
|
|||||||
beatmapInfo.Status = BeatmapOnlineStatus.LocallyModified;
|
beatmapInfo.Status = BeatmapOnlineStatus.LocallyModified;
|
||||||
beatmapInfo.ResetOnlineInfo();
|
beatmapInfo.ResetOnlineInfo();
|
||||||
|
|
||||||
using (var stream = new MemoryStream())
|
Realm.Write(r =>
|
||||||
{
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
|
using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
|
||||||
new LegacyBeatmapEncoder(beatmapContent, beatmapSkin).Encode(sw);
|
new LegacyBeatmapEncoder(beatmapContent, beatmapSkin).Encode(sw);
|
||||||
|
|
||||||
@ -458,23 +459,20 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
updateHashAndMarkDirty(setInfo);
|
updateHashAndMarkDirty(setInfo);
|
||||||
|
|
||||||
Realm.Write(r =>
|
var liveBeatmapSet = r.Find<BeatmapSetInfo>(setInfo.ID)!;
|
||||||
{
|
|
||||||
var liveBeatmapSet = r.Find<BeatmapSetInfo>(setInfo.ID)!;
|
|
||||||
|
|
||||||
setInfo.CopyChangesToRealm(liveBeatmapSet);
|
setInfo.CopyChangesToRealm(liveBeatmapSet);
|
||||||
|
|
||||||
if (transferCollections)
|
if (transferCollections)
|
||||||
beatmapInfo.TransferCollectionReferences(r, oldMd5Hash);
|
beatmapInfo.TransferCollectionReferences(r, oldMd5Hash);
|
||||||
|
|
||||||
liveBeatmapSet.Beatmaps.Single(b => b.ID == beatmapInfo.ID)
|
liveBeatmapSet.Beatmaps.Single(b => b.ID == beatmapInfo.ID)
|
||||||
.UpdateLocalScores(r);
|
.UpdateLocalScores(r);
|
||||||
|
|
||||||
// do not look up metadata.
|
// do not look up metadata.
|
||||||
// this is a locally-modified set now, so looking up metadata is busy work at best and harmful at worst.
|
// this is a locally-modified set now, so looking up metadata is busy work at best and harmful at worst.
|
||||||
ProcessBeatmap?.Invoke(liveBeatmapSet, MetadataLookupScope.None);
|
ProcessBeatmap?.Invoke(liveBeatmapSet, MetadataLookupScope.None);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Debug.Assert(beatmapInfo.BeatmapSet != null);
|
Debug.Assert(beatmapInfo.BeatmapSet != null);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
|
|||||||
return base.OnKeyDown(e);
|
return base.OnKeyDown(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
public virtual bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
||||||
{
|
{
|
||||||
if (e.Repeat)
|
if (e.Repeat)
|
||||||
return false;
|
return false;
|
||||||
|
@ -8,10 +8,12 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics.UserInterfaceV2;
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -95,6 +97,18 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
||||||
|
{
|
||||||
|
switch (e.Action)
|
||||||
|
{
|
||||||
|
case GlobalAction.Select:
|
||||||
|
createButton.TriggerClick();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnPressed(e);
|
||||||
|
}
|
||||||
|
|
||||||
private void createPreset()
|
private void createPreset()
|
||||||
{
|
{
|
||||||
realm.Write(r => r.Add(new ModPreset
|
realm.Write(r => r.Add(new ModPreset
|
||||||
|
@ -8,11 +8,13 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics.UserInterfaceV2;
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -130,6 +132,25 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(nameTextBox));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
||||||
|
{
|
||||||
|
switch (e.Action)
|
||||||
|
{
|
||||||
|
case GlobalAction.Select:
|
||||||
|
saveButton.TriggerClick();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnPressed(e);
|
||||||
|
}
|
||||||
|
|
||||||
private void useCurrentMods()
|
private void useCurrentMods()
|
||||||
{
|
{
|
||||||
saveableMods = selectedMods.Value.ToHashSet();
|
saveableMods = selectedMods.Value.ToHashSet();
|
||||||
@ -150,13 +171,6 @@ namespace osu.Game.Overlays.Mods
|
|||||||
return !saveableMods.SetEquals(selectedMods.Value);
|
return !saveableMods.SetEquals(selectedMods.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(nameTextBox));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void save()
|
private void save()
|
||||||
{
|
{
|
||||||
preset.PerformWrite(s =>
|
preset.PerformWrite(s =>
|
||||||
|
@ -48,7 +48,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
/// Contrary to <see cref="OsuGameBase.AvailableMods"/> and <see cref="globalAvailableMods"/>, the <see cref="Mod"/> instances
|
/// Contrary to <see cref="OsuGameBase.AvailableMods"/> and <see cref="globalAvailableMods"/>, the <see cref="Mod"/> instances
|
||||||
/// inside the <see cref="ModState"/> objects are owned solely by this <see cref="ModSelectOverlay"/> instance.
|
/// inside the <see cref="ModState"/> objects are owned solely by this <see cref="ModSelectOverlay"/> instance.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public Bindable<Dictionary<ModType, IReadOnlyList<ModState>>> AvailableMods { get; } = new Bindable<Dictionary<ModType, IReadOnlyList<ModState>>>(new Dictionary<ModType, IReadOnlyList<ModState>>());
|
public Bindable<Dictionary<ModType, IReadOnlyList<ModState>>> AvailableMods { get; } =
|
||||||
|
new Bindable<Dictionary<ModType, IReadOnlyList<ModState>>>(new Dictionary<ModType, IReadOnlyList<ModState>>());
|
||||||
|
|
||||||
private Func<Mod, bool> isValidMod = _ => true;
|
private Func<Mod, bool> isValidMod = _ => true;
|
||||||
|
|
||||||
@ -636,12 +637,9 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
case GlobalAction.Select:
|
case GlobalAction.Select:
|
||||||
{
|
{
|
||||||
// Pressing select should select first filtered mod or completely hide the overlay in one shot if search term is empty.
|
// Pressing select should select first filtered mod if a search is in progress.
|
||||||
if (string.IsNullOrEmpty(SearchTerm))
|
if (string.IsNullOrEmpty(SearchTerm))
|
||||||
{
|
|
||||||
hideOverlay(true);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
ModState? firstMod = columnFlow.Columns.OfType<ModColumn>().FirstOrDefault(m => m.IsPresent)?.AvailableMods.FirstOrDefault(x => x.Visible);
|
ModState? firstMod = columnFlow.Columns.OfType<ModColumn>().FirstOrDefault(m => m.IsPresent)?.AvailableMods.FirstOrDefault(x => x.Visible);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user