mirror of
https://github.com/ppy/osu.git
synced 2025-03-03 20:02:54 +08:00
Add loser progressions
This commit is contained in:
parent
c7c55f2139
commit
d2ce974ba8
@ -64,6 +64,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
pairing.Grouping.BindValueChanged(_ => updateWinConditions());
|
pairing.Grouping.BindValueChanged(_ => updateWinConditions());
|
||||||
pairing.Completed.BindValueChanged(_ => updateProgression());
|
pairing.Completed.BindValueChanged(_ => updateProgression());
|
||||||
pairing.Progression.BindValueChanged(_ => updateProgression());
|
pairing.Progression.BindValueChanged(_ => updateProgression());
|
||||||
|
pairing.LosersProgression.BindValueChanged(_ => updateProgression());
|
||||||
|
|
||||||
updateTeams();
|
updateTeams();
|
||||||
}
|
}
|
||||||
@ -102,12 +103,21 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
{
|
{
|
||||||
var progression = Pairing.Progression?.Value;
|
var progression = Pairing.Progression?.Value;
|
||||||
|
|
||||||
if (progression == null) return;
|
if (progression != null)
|
||||||
|
{
|
||||||
|
bool progressionAbove = progression.ID < Pairing.ID;
|
||||||
|
|
||||||
bool progressionAbove = progression.ID < Pairing.ID;
|
var destinationForWinner = progressionAbove || progression.Team1.Value != null && progression.Team1.Value != Pairing.Winner ? progression.Team2 : progression.Team1;
|
||||||
|
destinationForWinner.Value = Pairing.Winner;
|
||||||
|
}
|
||||||
|
|
||||||
var destinationForWinner = progressionAbove ? progression.Team2 : progression.Team1;
|
if ((progression = Pairing.LosersProgression?.Value) != null)
|
||||||
destinationForWinner.Value = Pairing.Winner;
|
{
|
||||||
|
bool progressionAbove = progression.ID < Pairing.ID;
|
||||||
|
|
||||||
|
var destinationForLoser = progressionAbove || progression.Team1.Value != null && progression.Team1.Value != Pairing.Winner ? progression.Team2 : progression.Team1;
|
||||||
|
destinationForLoser.Value = Pairing.Loser;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateWinConditions()
|
private void updateWinConditions()
|
||||||
@ -197,6 +207,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
{
|
{
|
||||||
Selected = false;
|
Selected = false;
|
||||||
Pairing.Progression.Value = null;
|
Pairing.Progression.Value = null;
|
||||||
|
Pairing.LosersProgression.Value = null;
|
||||||
|
|
||||||
Expire();
|
Expire();
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,10 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (pairing.Progression.Value.Completed)
|
||||||
|
// don't allow changing scores if the match has a progression. can cause large data loss
|
||||||
|
return false;
|
||||||
|
|
||||||
if (score.Value > 0)
|
if (score.Value > 0)
|
||||||
score.Value--;
|
score.Value--;
|
||||||
else
|
else
|
||||||
@ -168,7 +172,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
|
|
||||||
return new MenuItem[]
|
return new MenuItem[]
|
||||||
{
|
{
|
||||||
new OsuMenuItem("Join with", MenuItemType.Standard, () => manager.RequestJoin(pairing)),
|
new OsuMenuItem("Join with", MenuItemType.Standard, () => manager.RequestJoin(pairing, false)),
|
||||||
|
new OsuMenuItem("Join with (loser)", MenuItemType.Standard, () => manager.RequestJoin(pairing, true)),
|
||||||
new OsuMenuItem("Remove", MenuItemType.Destructive, () => manager.Remove(pairing)),
|
new OsuMenuItem("Remove", MenuItemType.Destructive, () => manager.Remove(pairing)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
public class LadderInfo
|
public class LadderInfo
|
||||||
{
|
{
|
||||||
public List<MatchPairing> Pairings = new List<MatchPairing>();
|
public List<MatchPairing> Pairings = new List<MatchPairing>();
|
||||||
public List<(int, int)> Progressions = new List<(int, int)>();
|
public List<TournamentProgression> Progressions = new List<TournamentProgression>();
|
||||||
public List<TournamentGrouping> Groupings = new List<TournamentGrouping>();
|
public List<TournamentGrouping> Groupings = new List<TournamentGrouping>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
private OsuTextBox textboxTeam1;
|
private OsuTextBox textboxTeam1;
|
||||||
private OsuTextBox textboxTeam2;
|
private OsuTextBox textboxTeam2;
|
||||||
private SettingsDropdown<TournamentGrouping> groupingDropdown;
|
private SettingsDropdown<TournamentGrouping> groupingDropdown;
|
||||||
|
private PlayerCheckbox losersCheckbox;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private LadderEditorInfo editorInfo { get; set; } = null;
|
private LadderEditorInfo editorInfo { get; set; } = null;
|
||||||
@ -32,7 +33,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
{
|
{
|
||||||
var teamEntries = editorInfo.Teams;
|
var teamEntries = editorInfo.Teams;
|
||||||
|
|
||||||
var groupingOptions = editorInfo.Groupings.Select(g => new KeyValuePair<string, TournamentGrouping>(g.Name, g)).Prepend(new KeyValuePair<string, TournamentGrouping>("None", new TournamentGrouping()));
|
var groupingOptions = editorInfo.Groupings.Select(g => new KeyValuePair<string, TournamentGrouping>(g.Name, g))
|
||||||
|
.Prepend(new KeyValuePair<string, TournamentGrouping>("None", new TournamentGrouping()));
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
@ -78,6 +80,11 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
Bindable = new Bindable<TournamentGrouping>(),
|
Bindable = new Bindable<TournamentGrouping>(),
|
||||||
Items = groupingOptions
|
Items = groupingOptions
|
||||||
},
|
},
|
||||||
|
losersCheckbox = new PlayerCheckbox
|
||||||
|
{
|
||||||
|
LabelText = "Losers Bracket",
|
||||||
|
Bindable = new Bindable<bool>()
|
||||||
|
}
|
||||||
// new Container
|
// new Container
|
||||||
// {
|
// {
|
||||||
// RelativeSizeAxes = Axes.X,
|
// RelativeSizeAxes = Axes.X,
|
||||||
@ -111,6 +118,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
textboxTeam1.Text = selection?.Team1.Value?.Acronym;
|
textboxTeam1.Text = selection?.Team1.Value?.Acronym;
|
||||||
textboxTeam2.Text = selection?.Team2.Value?.Acronym;
|
textboxTeam2.Text = selection?.Team2.Value?.Acronym;
|
||||||
groupingDropdown.Bindable.Value = selection?.Grouping.Value ?? groupingOptions.First().Value;
|
groupingDropdown.Bindable.Value = selection?.Grouping.Value ?? groupingOptions.First().Value;
|
||||||
|
losersCheckbox.Current.Value = selection?.Losers.Value ?? false;
|
||||||
};
|
};
|
||||||
|
|
||||||
textboxTeam1.OnCommit = (val, newText) =>
|
textboxTeam1.OnCommit = (val, newText) =>
|
||||||
@ -131,6 +139,12 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
editorInfo.Selected.Value.Grouping.Value = grouping;
|
editorInfo.Selected.Value.Grouping.Value = grouping;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
losersCheckbox.Current.ValueChanged += losers =>
|
||||||
|
{
|
||||||
|
if (editorInfo.Selected.Value != null)
|
||||||
|
editorInfo.Selected.Value.Losers.Value = losers;
|
||||||
|
};
|
||||||
|
|
||||||
// sliderBestOf.Bindable.ValueChanged += val =>
|
// sliderBestOf.Bindable.ValueChanged += val =>
|
||||||
// {
|
// {
|
||||||
// if (editorInfo.Selected.Value != null) editorInfo.Selected.Value.BestOf.Value = (int)val;
|
// if (editorInfo.Selected.Value != null) editorInfo.Selected.Value.BestOf.Value = (int)val;
|
||||||
|
@ -25,12 +25,17 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
|
|
||||||
public readonly Bindable<bool> Completed = new Bindable<bool>();
|
public readonly Bindable<bool> Completed = new Bindable<bool>();
|
||||||
|
|
||||||
|
public readonly Bindable<bool> Losers = new Bindable<bool>();
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public readonly Bindable<TournamentGrouping> Grouping = new Bindable<TournamentGrouping>();
|
public readonly Bindable<TournamentGrouping> Grouping = new Bindable<TournamentGrouping>();
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public readonly Bindable<MatchPairing> Progression = new Bindable<MatchPairing>();
|
public readonly Bindable<MatchPairing> Progression = new Bindable<MatchPairing>();
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public readonly Bindable<MatchPairing> LosersProgression = new Bindable<MatchPairing>();
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public Point Position;
|
public Point Position;
|
||||||
|
|
||||||
@ -47,6 +52,9 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public TournamentTeam Winner => !Completed.Value ? null : Team1Score.Value > Team2Score.Value ? Team1.Value : Team2.Value;
|
public TournamentTeam Winner => !Completed.Value ? null : Team1Score.Value > Team2Score.Value ? Team1.Value : Team2.Value;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public TournamentTeam Loser => !Completed.Value ? null : Team1Score.Value > Team2Score.Value ? Team2.Value : Team1.Value;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove scores from the match, in case of a false click or false start.
|
/// Remove scores from the match, in case of a false click or false start.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||||
|
{
|
||||||
|
public class TournamentProgression
|
||||||
|
{
|
||||||
|
public int Item1;
|
||||||
|
public int Item2;
|
||||||
|
|
||||||
|
public bool Losers;
|
||||||
|
|
||||||
|
public TournamentProgression(int item1, int item2, bool losers = false)
|
||||||
|
{
|
||||||
|
Item1 = item1;
|
||||||
|
Item2 = item2;
|
||||||
|
Losers = losers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ namespace osu.Game.Tournament.Screens.Ladder
|
|||||||
{
|
{
|
||||||
public class DrawableTournamentGrouping : CompositeDrawable
|
public class DrawableTournamentGrouping : CompositeDrawable
|
||||||
{
|
{
|
||||||
public DrawableTournamentGrouping(TournamentGrouping grouping)
|
public DrawableTournamentGrouping(TournamentGrouping grouping, bool losers = false)
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
InternalChild = new FillFlowContainer
|
InternalChild = new FillFlowContainer
|
||||||
@ -27,7 +27,7 @@ namespace osu.Game.Tournament.Screens.Ladder
|
|||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = grouping.Name.ToUpper(),
|
Text = ((losers ? "Losers " : "") + grouping.Name).ToUpper(),
|
||||||
Font = "Exo2.0-Bold",
|
Font = "Exo2.0-Bold",
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
Anchor = Anchor.TopCentre
|
Anchor = Anchor.TopCentre
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Caching;
|
using osu.Framework.Caching;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
@ -54,7 +53,7 @@ namespace osu.Game.Tournament.Screens.Ladder
|
|||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
paths = new Container<Path> { RelativeSizeAxes = Axes.Both },
|
paths = new Container<Path> { RelativeSizeAxes = Axes.Both },
|
||||||
headings = new Container() { RelativeSizeAxes = Axes.Both },
|
headings = new Container { RelativeSizeAxes = Axes.Both },
|
||||||
pairingsContainer = new Container<DrawableMatchPairing> { RelativeSizeAxes = Axes.Both },
|
pairingsContainer = new Container<DrawableMatchPairing> { RelativeSizeAxes = Axes.Both },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -75,7 +74,12 @@ namespace osu.Game.Tournament.Screens.Ladder
|
|||||||
if (src == null) throw new InvalidOperationException();
|
if (src == null) throw new InvalidOperationException();
|
||||||
|
|
||||||
if (dest != null)
|
if (dest != null)
|
||||||
src.Progression.Value = dest;
|
{
|
||||||
|
if (pair.Losers)
|
||||||
|
src.LosersProgression.Value = dest;
|
||||||
|
else
|
||||||
|
src.Progression.Value = dest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var pairing in info.Pairings)
|
foreach (var pairing in info.Pairings)
|
||||||
@ -99,10 +103,9 @@ namespace osu.Game.Tournament.Screens.Ladder
|
|||||||
return new LadderInfo
|
return new LadderInfo
|
||||||
{
|
{
|
||||||
Pairings = pairings,
|
Pairings = pairings,
|
||||||
Progressions = pairings
|
Progressions = pairings.Where(p => p.Progression.Value != null).Select(p => new TournamentProgression(p.ID, p.Progression.Value.ID)).Concat(
|
||||||
.Where(p => p.Progression.Value != null)
|
pairings.Where(p => p.LosersProgression.Value != null).Select(p => new TournamentProgression(p.ID, p.LosersProgression.Value.ID, true)))
|
||||||
.Select(p => (p.ID, p.Progression.Value.ID))
|
.ToList(),
|
||||||
.ToList(),
|
|
||||||
Groupings = editorInfo.Groupings
|
Groupings = editorInfo.Groupings
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -120,7 +123,7 @@ namespace osu.Game.Tournament.Screens.Ladder
|
|||||||
{
|
{
|
||||||
new OsuMenuItem("Create new match", MenuItemType.Highlighted, () =>
|
new OsuMenuItem("Create new match", MenuItemType.Highlighted, () =>
|
||||||
{
|
{
|
||||||
var pos = ToLocalSpace(GetContainingInputManager().CurrentState.Mouse.Position);
|
var pos = pairingsContainer.ToLocalSpace(GetContainingInputManager().CurrentState.Mouse.Position);
|
||||||
addPairing(new MatchPairing { Position = new Point((int)pos.X, (int)pos.Y) });
|
addPairing(new MatchPairing { Position = new Point((int)pos.X, (int)pos.Y) });
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
@ -161,7 +164,7 @@ namespace osu.Game.Tournament.Screens.Ladder
|
|||||||
|
|
||||||
foreach (var group in editorInfo.Groupings)
|
foreach (var group in editorInfo.Groupings)
|
||||||
{
|
{
|
||||||
var topPairing = pairingsContainer.Where(p => p.Pairing.Grouping.Value == group).OrderBy(p => p.Y).FirstOrDefault();
|
var topPairing = pairingsContainer.Where(p => !p.Pairing.Losers && p.Pairing.Grouping.Value == group).OrderBy(p => p.Y).FirstOrDefault();
|
||||||
|
|
||||||
if (topPairing == null) continue;
|
if (topPairing == null) continue;
|
||||||
|
|
||||||
@ -173,25 +176,44 @@ namespace osu.Game.Tournament.Screens.Ladder
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var group in editorInfo.Groupings)
|
||||||
|
{
|
||||||
|
var topPairing = pairingsContainer.Where(p => p.Pairing.Losers && p.Pairing.Grouping.Value == group).OrderBy(p => p.Y).FirstOrDefault();
|
||||||
|
|
||||||
|
if (topPairing == null) continue;
|
||||||
|
|
||||||
|
headings.Add(new DrawableTournamentGrouping(group, true)
|
||||||
|
{
|
||||||
|
Position = headings.ToLocalSpace((topPairing.ScreenSpaceDrawQuad.TopLeft + topPairing.ScreenSpaceDrawQuad.TopRight) / 2),
|
||||||
|
Margin = new MarginPadding { Bottom = 10 },
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
layout.Validate();
|
layout.Validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestJoin(MatchPairing pairing) => AddInternal(new JoinRequestHandler(pairingsContainer, pairing));
|
public void RequestJoin(MatchPairing pairing, bool losers) => AddInternal(new JoinRequestHandler(pairingsContainer, pairing, losers));
|
||||||
|
|
||||||
private class JoinRequestHandler : CompositeDrawable
|
private class JoinRequestHandler : CompositeDrawable
|
||||||
{
|
{
|
||||||
private readonly Container<DrawableMatchPairing> pairingsContainer;
|
private readonly Container<DrawableMatchPairing> pairingsContainer;
|
||||||
public readonly MatchPairing Source;
|
public readonly MatchPairing Source;
|
||||||
|
private readonly bool losers;
|
||||||
|
|
||||||
private ProgressionPath path;
|
private ProgressionPath path;
|
||||||
|
|
||||||
public JoinRequestHandler(Container<DrawableMatchPairing> pairingsContainer, MatchPairing source)
|
public JoinRequestHandler(Container<DrawableMatchPairing> pairingsContainer, MatchPairing source, bool losers)
|
||||||
{
|
{
|
||||||
this.pairingsContainer = pairingsContainer;
|
this.pairingsContainer = pairingsContainer;
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
Source = source;
|
Source = source;
|
||||||
Source.Progression.Value = null;
|
this.losers = losers;
|
||||||
|
if (losers)
|
||||||
|
Source.LosersProgression.Value = null;
|
||||||
|
else
|
||||||
|
Source.Progression.Value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DrawableMatchPairing findTarget(InputState state) => pairingsContainer.FirstOrDefault(d => d.ReceiveMouseInputAt(state.Mouse.NativeState.Position));
|
private DrawableMatchPairing findTarget(InputState state) => pairingsContainer.FirstOrDefault(d => d.ReceiveMouseInputAt(state.Mouse.NativeState.Position));
|
||||||
@ -221,7 +243,13 @@ namespace osu.Game.Tournament.Screens.Ladder
|
|||||||
if (found != null)
|
if (found != null)
|
||||||
{
|
{
|
||||||
if (found.Pairing != Source)
|
if (found.Pairing != Source)
|
||||||
Source.Progression.Value = found.Pairing;
|
{
|
||||||
|
if (losers)
|
||||||
|
Source.LosersProgression.Value = found.Pairing;
|
||||||
|
else
|
||||||
|
Source.Progression.Value = found.Pairing;
|
||||||
|
}
|
||||||
|
|
||||||
Expire();
|
Expire();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user