Grouping -> Round

This commit is contained in:
Dean Herbert 2019-06-18 14:44:15 +09:00
parent 40eb6f4986
commit 4f5abeb79f
21 changed files with 92 additions and 92 deletions

View File

@ -1,7 +1,7 @@
// 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 osu.Game.Tournament.Screens.Groupings;
using osu.Game.Tournament.Screens.Rounds;
namespace osu.Game.Tournament.Tests
{
@ -9,7 +9,7 @@ public class TestSceneGroupingsEditorScreen : LadderTestScene
{
public TestSceneGroupingsEditorScreen()
{
Add(new GroupingsEditorScreen());
Add(new RoundEditorScreen());
}
}
}

View File

@ -21,7 +21,7 @@ private void load()
var pairing = new MatchPairing();
pairing.Team1.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "USA");
pairing.Team2.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "JPN");
pairing.Grouping.Value = Ladder.Groupings.FirstOrDefault(g => g.Name.Value == "Finals");
pairing.Round.Value = Ladder.Rounds.FirstOrDefault(g => g.Name.Value == "Finals");
currentMatch.Value = pairing;
Add(new TeamIntroScreen

View File

@ -21,7 +21,7 @@ private void load()
var pairing = new MatchPairing();
pairing.Team1.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "USA");
pairing.Team2.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "JPN");
pairing.Grouping.Value = Ladder.Groupings.FirstOrDefault(g => g.Name.Value == "Finals");
pairing.Round.Value = Ladder.Rounds.FirstOrDefault(g => g.Name.Value == "Finals");
currentMatch.Value = pairing;
Add(new TeamWinScreen

View File

@ -61,7 +61,7 @@ private void load(LadderInfo ladder, GameHost host)
{
lastBeatmapId = beatmapId;
var existing = ladder.CurrentMatch.Value?.Grouping.Value?.Beatmaps.FirstOrDefault(b => b.ID == beatmapId && b.BeatmapInfo != null);
var existing = ladder.CurrentMatch.Value?.Round.Value?.Beatmaps.FirstOrDefault(b => b.ID == beatmapId && b.BeatmapInfo != null);
if (existing != null)
Beatmap.Value = existing.BeatmapInfo;

View File

@ -12,7 +12,7 @@ namespace osu.Game.Tournament
public class LadderInfo
{
public BindableList<MatchPairing> Pairings = new BindableList<MatchPairing>();
public BindableList<TournamentGrouping> Groupings = new BindableList<TournamentGrouping>();
public BindableList<TournamentRound> Rounds = new BindableList<TournamentRound>();
public BindableList<TournamentTeam> Teams = new BindableList<TournamentTeam>();
// only used for serialisation

View File

@ -218,7 +218,7 @@ private void matchChanged(ValueChangedEvent<MatchPairing> match)
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = Color4.White,
Text = match.NewValue.Grouping.Value?.Name.Value ?? "Unknown Grouping",
Text = match.NewValue.Round.Value?.Name.Value ?? "Unknown Round",
Font = TournamentFont.GetFont(typeface: TournamentTypeface.Aquatico, weight: FontWeight.Regular, size: 18),
},
};

View File

@ -79,7 +79,7 @@ public DrawableMatchPairing(MatchPairing pairing, bool editor = false)
boundReference(pairing.Team2).BindValueChanged(_ => updateTeams());
boundReference(pairing.Team1Score).BindValueChanged(_ => updateWinConditions());
boundReference(pairing.Team2Score).BindValueChanged(_ => updateWinConditions());
boundReference(pairing.Grouping).BindValueChanged(_ =>
boundReference(pairing.Round).BindValueChanged(_ =>
{
updateWinConditions();
Changed?.Invoke();
@ -210,12 +210,12 @@ private void transferProgression(MatchPairing destination, TournamentTeam team)
private void updateWinConditions()
{
if (Pairing.Grouping.Value == null) return;
if (Pairing.Round.Value == null) return;
var instaWinAmount = Pairing.Grouping.Value.BestOf.Value / 2;
var instaWinAmount = Pairing.Round.Value.BestOf.Value / 2;
Pairing.Completed.Value = Pairing.Grouping.Value.BestOf.Value > 0
&& (Pairing.Team1Score.Value + Pairing.Team2Score.Value >= Pairing.Grouping.Value.BestOf.Value || Pairing.Team1Score.Value > instaWinAmount || Pairing.Team2Score.Value > instaWinAmount);
Pairing.Completed.Value = Pairing.Round.Value.BestOf.Value > 0
&& (Pairing.Team1Score.Value + Pairing.Team2Score.Value >= Pairing.Round.Value.BestOf.Value || Pairing.Team1Score.Value > instaWinAmount || Pairing.Team2Score.Value > instaWinAmount);
}
protected override void LoadComplete()

View File

@ -11,7 +11,7 @@
namespace osu.Game.Tournament.Screens.Ladder.Components
{
public class DrawableTournamentGrouping : CompositeDrawable
public class DrawableTournamentRound : CompositeDrawable
{
[UsedImplicitly]
private readonly Bindable<string> name;
@ -19,7 +19,7 @@ public class DrawableTournamentGrouping : CompositeDrawable
[UsedImplicitly]
private readonly Bindable<string> description;
public DrawableTournamentGrouping(TournamentGrouping grouping, bool losers = false)
public DrawableTournamentRound(TournamentRound round, bool losers = false)
{
OsuSpriteText textName;
OsuSpriteText textDescription;
@ -47,11 +47,11 @@ public DrawableTournamentGrouping(TournamentGrouping grouping, bool losers = fal
}
};
name = grouping.Name.GetBoundCopy();
name.BindValueChanged(n => textName.Text = ((losers ? "Losers " : "") + grouping.Name).ToUpper(), true);
name = round.Name.GetBoundCopy();
name.BindValueChanged(n => textName.Text = ((losers ? "Losers " : "") + round.Name).ToUpper(), true);
description = grouping.Name.GetBoundCopy();
description.BindValueChanged(n => textDescription.Text = grouping.Description.Value.ToUpper(), true);
description = round.Name.GetBoundCopy();
description.BindValueChanged(n => textDescription.Text = round.Description.Value.ToUpper(), true);
}
}
}

View File

@ -20,7 +20,7 @@ public class LadderEditorSettings : PlayerSettingsGroup
protected override string Title => @"ladder";
private SettingsDropdown<TournamentGrouping> groupingDropdown;
private SettingsDropdown<TournamentRound> roundDropdown;
private PlayerCheckbox losersCheckbox;
private DateTextBox dateTimeBox;
private SettingsTeamDropdown team1Dropdown;
@ -39,14 +39,14 @@ private void load()
{
team1Dropdown = new SettingsTeamDropdown(ladderInfo.Teams) { LabelText = "Team 1" },
team2Dropdown = new SettingsTeamDropdown(ladderInfo.Teams) { LabelText = "Team 2" },
groupingDropdown = new SettingsGroupingDropdown(ladderInfo.Groupings) { LabelText = "Grouping" },
roundDropdown = new SettingsRoundDropdown(ladderInfo.Rounds) { LabelText = "Round" },
losersCheckbox = new PlayerCheckbox { LabelText = "Losers Bracket" },
dateTimeBox = new DateTextBox { LabelText = "Match Time" },
};
editorInfo.Selected.ValueChanged += selection =>
{
groupingDropdown.Bindable = selection.NewValue?.Grouping;
roundDropdown.Bindable = selection.NewValue?.Round;
losersCheckbox.Current = selection.NewValue?.Losers;
dateTimeBox.Bindable = selection.NewValue?.Date;
@ -54,11 +54,11 @@ private void load()
team2Dropdown.Bindable = selection.NewValue?.Team2;
};
groupingDropdown.Bindable.ValueChanged += grouping =>
roundDropdown.Bindable.ValueChanged += round =>
{
if (editorInfo.Selected.Value?.Date.Value < grouping.NewValue?.StartDate.Value)
if (editorInfo.Selected.Value?.Date.Value < round.NewValue?.StartDate.Value)
{
editorInfo.Selected.Value.Date.Value = grouping.NewValue.StartDate.Value;
editorInfo.Selected.Value.Date.Value = round.NewValue.StartDate.Value;
editorInfo.Selected.TriggerChange();
}
};
@ -79,17 +79,17 @@ protected override void OnHoverLost(HoverLostEvent e)
{
}
private class SettingsGroupingDropdown : SettingsDropdown<TournamentGrouping>
private class SettingsRoundDropdown : SettingsDropdown<TournamentRound>
{
public SettingsGroupingDropdown(BindableList<TournamentGrouping> groupings)
public SettingsRoundDropdown(BindableList<TournamentRound> rounds)
{
Bindable = new Bindable<TournamentGrouping>();
Bindable = new Bindable<TournamentRound>();
foreach (var g in groupings.Prepend(new TournamentGrouping()))
add(g);
foreach (var r in rounds.Prepend(new TournamentRound()))
add(r);
groupings.ItemsRemoved += items => items.ForEach(i => Control.RemoveDropdownItem(i));
groupings.ItemsAdded += items => items.ForEach(add);
rounds.ItemsRemoved += items => items.ForEach(i => Control.RemoveDropdownItem(i));
rounds.ItemsAdded += items => items.ForEach(add);
}
private readonly List<IUnbindable> refBindables = new List<IUnbindable>();
@ -102,13 +102,13 @@ private T boundReference<T>(T obj)
return obj;
}
private void add(TournamentGrouping grouping)
private void add(TournamentRound round)
{
Control.AddDropdownItem(grouping);
boundReference(grouping.Name).BindValueChanged(_ =>
Control.AddDropdownItem(round);
boundReference(round.Name).BindValueChanged(_ =>
{
Control.RemoveDropdownItem(grouping);
Control.AddDropdownItem(grouping);
Control.RemoveDropdownItem(round);
Control.AddDropdownItem(round);
});
}
}
@ -117,8 +117,8 @@ private class SettingsTeamDropdown : SettingsDropdown<TournamentTeam>
{
public SettingsTeamDropdown(BindableList<TournamentTeam> teams)
{
foreach (var g in teams.Prepend(new TournamentTeam()))
add(g);
foreach (var t in teams.Prepend(new TournamentTeam()))
add(t);
teams.ItemsRemoved += items => items.ForEach(i => Control.RemoveDropdownItem(i));
teams.ItemsAdded += items => items.ForEach(add);

View File

@ -51,7 +51,7 @@ public List<string> Acronyms
public readonly ObservableCollection<BeatmapChoice> PicksBans = new ObservableCollection<BeatmapChoice>();
[JsonIgnore]
public readonly Bindable<TournamentGrouping> Grouping = new Bindable<TournamentGrouping>();
public readonly Bindable<TournamentRound> Round = new Bindable<TournamentRound>();
[JsonIgnore]
public readonly Bindable<MatchPairing> Progression = new Bindable<MatchPairing>();
@ -90,7 +90,7 @@ public MatchPairing(TournamentTeam team1 = null, TournamentTeam team2 = null)
[JsonIgnore]
public TournamentTeam Loser => !Completed.Value ? null : Team1Score.Value > Team2Score.Value ? Team2.Value : Team1.Value;
public int PointsToWin => Grouping.Value?.BestOf.Value / 2 + 1 ?? 0;
public int PointsToWin => Round.Value?.BestOf.Value / 2 + 1 ?? 0;
/// <summary>
/// Remove scores from the match, in case of a false click or false start.

View File

@ -5,7 +5,7 @@
namespace osu.Game.Tournament.Screens.Ladder.Components
{
public class GroupingBeatmap
public class RoundBeatmap
{
public int ID;
public string Mods;

View File

@ -9,7 +9,7 @@
namespace osu.Game.Tournament.Screens.Ladder.Components
{
[Serializable]
public class TournamentGrouping
public class TournamentRound
{
public readonly Bindable<string> Name = new Bindable<string>();
public readonly Bindable<string> Description = new Bindable<string>();
@ -17,7 +17,7 @@ public class TournamentGrouping
public readonly BindableInt BestOf = new BindableInt(9) { Default = 9, MinValue = 3, MaxValue = 23 };
[JsonProperty]
public readonly List<GroupingBeatmap> Beatmaps = new List<GroupingBeatmap>();
public readonly List<RoundBeatmap> Beatmaps = new List<RoundBeatmap>();
public readonly Bindable<DateTimeOffset> StartDate = new Bindable<DateTimeOffset>();

View File

@ -66,8 +66,8 @@ void addPairing(MatchPairing pairing) =>
foreach (var pairing in LadderInfo.Pairings)
addPairing(pairing);
LadderInfo.Groupings.ItemsAdded += _ => layout.Invalidate();
LadderInfo.Groupings.ItemsRemoved += _ => layout.Invalidate();
LadderInfo.Rounds.ItemsAdded += _ => layout.Invalidate();
LadderInfo.Rounds.ItemsRemoved += _ => layout.Invalidate();
LadderInfo.Pairings.ItemsAdded += pairings =>
{
@ -138,13 +138,13 @@ protected virtual void UpdateLayout()
}
}
foreach (var group in LadderInfo.Groupings)
foreach (var round in LadderInfo.Rounds)
{
var topPairing = PairingsContainer.Where(p => !p.Pairing.Losers.Value && p.Pairing.Grouping.Value == group).OrderBy(p => p.Y).FirstOrDefault();
var topPairing = PairingsContainer.Where(p => !p.Pairing.Losers.Value && p.Pairing.Round.Value == round).OrderBy(p => p.Y).FirstOrDefault();
if (topPairing == null) continue;
headings.Add(new DrawableTournamentGrouping(group)
headings.Add(new DrawableTournamentRound(round)
{
Position = headings.ToLocalSpace((topPairing.ScreenSpaceDrawQuad.TopLeft + topPairing.ScreenSpaceDrawQuad.TopRight) / 2),
Margin = new MarginPadding { Bottom = 10 },
@ -152,13 +152,13 @@ protected virtual void UpdateLayout()
});
}
foreach (var group in LadderInfo.Groupings)
foreach (var round in LadderInfo.Rounds)
{
var topPairing = PairingsContainer.Where(p => p.Pairing.Losers.Value && p.Pairing.Grouping.Value == group).OrderBy(p => p.Y).FirstOrDefault();
var topPairing = PairingsContainer.Where(p => p.Pairing.Losers.Value && p.Pairing.Round.Value == round).OrderBy(p => p.Y).FirstOrDefault();
if (topPairing == null) continue;
headings.Add(new DrawableTournamentGrouping(group, true)
headings.Add(new DrawableTournamentRound(round, true)
{
Position = headings.ToLocalSpace((topPairing.ScreenSpaceDrawQuad.TopLeft + topPairing.ScreenSpaceDrawQuad.TopRight) / 2),
Margin = new MarginPadding { Bottom = 10 },

View File

@ -179,7 +179,7 @@ private void addForBeatmap(int beatmapId)
if (currentMatch.Value == null)
return;
if (currentMatch.Value.Grouping.Value.Beatmaps.All(b => b.BeatmapInfo.OnlineBeatmapID != beatmapId))
if (currentMatch.Value.Round.Value.Beatmaps.All(b => b.BeatmapInfo.OnlineBeatmapID != beatmapId))
// don't attempt to add if the beatmap isn't in our pool
return;
@ -207,12 +207,12 @@ private void matchChanged(ValueChangedEvent<MatchPairing> match)
{
mapFlows.Clear();
if (match.NewValue.Grouping.Value != null)
if (match.NewValue.Round.Value != null)
{
FillFlowContainer<TournamentBeatmapPanel> currentFlow = null;
string currentMod = null;
foreach (var b in match.NewValue.Grouping.Value.Beatmaps)
foreach (var b in match.NewValue.Round.Value.Beatmaps)
{
if (currentFlow == null || currentMod != b.Mods)
{

View File

@ -14,13 +14,13 @@
using osu.Game.Tournament.Screens.Ladder.Components;
using osuTK;
namespace osu.Game.Tournament.Screens.Groupings
namespace osu.Game.Tournament.Screens.Rounds
{
public class GroupingsEditorScreen : TournamentScreen, IProvideVideo
public class RoundEditorScreen : TournamentScreen, IProvideVideo
{
private readonly FillFlowContainer<GroupingRow> items;
private readonly FillFlowContainer<RoundRow> items;
public GroupingsEditorScreen()
public RoundEditorScreen()
{
AddRangeInternal(new Drawable[]
{
@ -35,7 +35,7 @@ public GroupingsEditorScreen()
Width = 0.9f,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Child = items = new FillFlowContainer<GroupingRow>
Child = items = new FillFlowContainer<RoundRow>
{
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.X,
@ -62,13 +62,13 @@ public GroupingsEditorScreen()
[BackgroundDependencyLoader]
private void load()
{
foreach (var g in LadderInfo.Groupings)
items.Add(new GroupingRow(g));
foreach (var r in LadderInfo.Rounds)
items.Add(new RoundRow(r));
}
private void addNew()
{
var grouping = new TournamentGrouping
var round = new TournamentRound
{
StartDate =
{
@ -76,22 +76,22 @@ private void addNew()
}
};
items.Add(new GroupingRow(grouping));
LadderInfo.Groupings.Add(grouping);
items.Add(new RoundRow(round));
LadderInfo.Rounds.Add(round);
}
public class GroupingRow : CompositeDrawable
public class RoundRow : CompositeDrawable
{
public readonly TournamentGrouping Grouping;
public readonly TournamentRound Round;
[Resolved]
private LadderInfo ladderInfo { get; set; }
public GroupingRow(TournamentGrouping grouping)
public RoundRow(TournamentRound round)
{
Margin = new MarginPadding(10);
Grouping = grouping;
Round = round;
InternalChildren = new Drawable[]
{
new Box
@ -113,25 +113,25 @@ public GroupingRow(TournamentGrouping grouping)
{
LabelText = "Name",
Width = 0.33f,
Bindable = Grouping.Name
Bindable = Round.Name
},
new SettingsTextBox
{
LabelText = "Description",
Width = 0.33f,
Bindable = Grouping.Description
Bindable = Round.Description
},
new DateTextBox
{
LabelText = "Start Time",
Width = 0.33f,
Bindable = Grouping.StartDate
Bindable = Round.StartDate
},
new SettingsSlider<int>
{
LabelText = "Best of",
Width = 0.33f,
Bindable = Grouping.BestOf
Bindable = Round.BestOf
},
}
},
@ -145,7 +145,7 @@ public GroupingRow(TournamentGrouping grouping)
Action = () =>
{
Expire();
ladderInfo.Groupings.Remove(Grouping);
ladderInfo.Rounds.Remove(Round);
},
}
};

View File

@ -110,7 +110,7 @@ private void matchChanged(ValueChangedEvent<MatchPairing> match)
{
Margin = new MarginPadding { Left = -10, Bottom = 10, Top = -5 },
Spacing = new Vector2(10, 0),
Text = match.NewValue.Grouping.Value?.Name.Value,
Text = match.NewValue.Round.Value?.Name.Value,
Colour = Color4.Black,
Font = OsuFont.GetFont(size: 20)
},

View File

@ -112,7 +112,7 @@ public RoundDisplay(MatchPairing pairing)
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Colour = col,
Text = pairing.Grouping.Value?.Name.Value ?? "Unknown Grouping",
Text = pairing.Round.Value?.Name.Value ?? "Unknown Round",
Spacing = new Vector2(10, 0),
Font = OsuFont.GetFont(size: 50, weight: FontWeight.Light)
},

View File

@ -133,7 +133,7 @@ public RoundDisplay(MatchPairing pairing)
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Colour = col,
Text = pairing.Grouping.Value?.Name.Value ?? "Unknown Grouping",
Text = pairing.Round.Value?.Name.Value ?? "Unknown Round",
Font = TournamentFont.GetFont(TournamentTypeface.Aquatico, 50, FontWeight.Light),
Spacing = new Vector2(10, 0),
},

View File

@ -66,8 +66,8 @@ public TeamsEditorScreen()
[BackgroundDependencyLoader]
private void load()
{
foreach (var g in LadderInfo.Teams)
items.Add(new TeamRow(g));
foreach (var t in LadderInfo.Teams)
items.Add(new TeamRow(t));
}
private void addNew()

View File

@ -12,9 +12,9 @@
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Screens.Drawings;
using osu.Game.Tournament.Screens.Gameplay;
using osu.Game.Tournament.Screens.Groupings;
using osu.Game.Tournament.Screens.Ladder;
using osu.Game.Tournament.Screens.MapPool;
using osu.Game.Tournament.Screens.Rounds;
using osu.Game.Tournament.Screens.Schedule;
using osu.Game.Tournament.Screens.Showcase;
using osu.Game.Tournament.Screens.TeamIntro;
@ -72,7 +72,7 @@ private void load(LadderInfo ladder, Storage storage)
new LadderScreen(),
new LadderEditorScreen(),
new TeamsEditorScreen(),
new GroupingsEditorScreen(),
new RoundEditorScreen(),
new ShowcaseScreen(),
new MapPoolScreen(),
new TeamIntroScreen(),
@ -106,7 +106,7 @@ private void load(LadderInfo ladder, Storage storage)
Children = new Drawable[]
{
new OsuButton { RelativeSizeAxes = Axes.X, Text = "Team Editor", Action = () => SetScreen(typeof(TeamsEditorScreen)) },
new OsuButton { RelativeSizeAxes = Axes.X, Text = "Groupings Editor", Action = () => SetScreen(typeof(GroupingsEditorScreen)) },
new OsuButton { RelativeSizeAxes = Axes.X, Text = "Rounds Editor", Action = () => SetScreen(typeof(RoundEditorScreen)) },
new OsuButton { RelativeSizeAxes = Axes.X, Text = "Bracket Editor", Action = () => SetScreen(typeof(LadderEditorScreen)) },
new Container { RelativeSizeAxes = Axes.X, Height = 50 },
new OsuButton { RelativeSizeAxes = Axes.X, Text = "Drawings", Action = () => SetScreen(typeof(DrawingsScreen)) },

View File

@ -107,7 +107,7 @@ private void readBracket()
{
conditional.Team1.Value = ladder.Teams.FirstOrDefault(t => t.Acronym.Value == conditional.Team1Acronym);
conditional.Team2.Value = ladder.Teams.FirstOrDefault(t => t.Acronym.Value == conditional.Team2Acronym);
conditional.Grouping.Value = pairing.Grouping.Value;
conditional.Round.Value = pairing.Round.Value;
}
}
@ -128,17 +128,17 @@ private void readBracket()
}
}
// link pairings to groupings
foreach (var group in ladder.Groupings)
foreach (var id in group.Pairings)
// link pairings to rounds
foreach (var round in ladder.Rounds)
foreach (var id in round.Pairings)
{
var found = ladder.Pairings.FirstOrDefault(p => p.ID == id);
if (found != null)
{
found.Grouping.Value = group;
if (group.StartDate.Value > found.Date.Value)
found.Date.Value = group.StartDate.Value;
found.Round.Value = round;
if (round.StartDate.Value > found.Date.Value)
found.Date.Value = round.StartDate.Value;
}
}
@ -179,8 +179,8 @@ private bool addBeatmaps()
{
bool addedInfo = false;
foreach (var g in ladder.Groupings)
foreach (var b in g.Beatmaps)
foreach (var r in ladder.Rounds)
foreach (var b in r.Beatmaps)
if (b.BeatmapInfo == null)
{
var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = b.ID });
@ -245,8 +245,8 @@ protected override void Update()
protected virtual void SaveChanges()
{
foreach (var g in ladder.Groupings)
g.Pairings = ladder.Pairings.Where(p => p.Grouping.Value == g).Select(p => p.ID).ToList();
foreach (var r in ladder.Rounds)
r.Pairings = ladder.Pairings.Where(p => p.Round.Value == r).Select(p => p.ID).ToList();
ladder.Progressions = ladder.Pairings.Where(p => p.Progression.Value != null).Select(p => new TournamentProgression(p.ID, p.Progression.Value.ID)).Concat(
ladder.Pairings.Where(p => p.LosersProgression.Value != null).Select(p => new TournamentProgression(p.ID, p.LosersProgression.Value.ID, true)))