1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-30 22:13:22 +08:00

Change to using a 'FreeStyle' boolean

This commit is contained in:
Dan Balasescu 2025-01-08 18:45:35 +09:00
parent 6579b05561
commit 9c05837b3a
No known key found for this signature in database
9 changed files with 49 additions and 50 deletions

View File

@ -57,11 +57,10 @@ namespace osu.Game.Online.Rooms
public double StarRating { get; set; } public double StarRating { get; set; }
/// <summary> /// <summary>
/// A non-<c>null</c> value indicates "freestyle" mode where players are able to individually select /// Indicates whether participants in the room are able to pick their own choice of beatmap difficulty and ruleset.
/// their own choice of beatmap (from the respective beatmap set) and ruleset to play in the room.
/// </summary> /// </summary>
[Key(11)] [Key(11)]
public int? BeatmapSetID { get; set; } public bool FreeStyle { get; set; }
[SerializationConstructor] [SerializationConstructor]
public MultiplayerPlaylistItem() public MultiplayerPlaylistItem()

View File

@ -68,11 +68,10 @@ namespace osu.Game.Online.Rooms
} }
/// <summary> /// <summary>
/// A non-<c>null</c> value indicates "freestyle" mode where players are able to individually select /// Indicates whether participants in the room are able to pick their own choice of beatmap difficulty and ruleset.
/// their own choice of beatmap (from the respective beatmap set) and ruleset to play in the room.
/// </summary> /// </summary>
[JsonProperty("beatmapset_id")] [JsonProperty("freestyle")]
public int? BeatmapSetId { get; set; } public bool FreeStyle { get; set; }
/// <summary> /// <summary>
/// A beatmap representing this playlist item. /// A beatmap representing this playlist item.
@ -108,7 +107,7 @@ namespace osu.Game.Online.Rooms
PlayedAt = item.PlayedAt; PlayedAt = item.PlayedAt;
RequiredMods = item.RequiredMods.ToArray(); RequiredMods = item.RequiredMods.ToArray();
AllowedMods = item.AllowedMods.ToArray(); AllowedMods = item.AllowedMods.ToArray();
BeatmapSetId = item.BeatmapSetID; FreeStyle = item.FreeStyle;
} }
public void MarkInvalid() => valid.Value = false; public void MarkInvalid() => valid.Value = false;
@ -128,8 +127,7 @@ namespace osu.Game.Online.Rooms
#endregion #endregion
public PlaylistItem With(Optional<long> id = default, Optional<IBeatmapInfo> beatmap = default, Optional<ushort?> playlistOrder = default, public PlaylistItem With(Optional<long> id = default, Optional<IBeatmapInfo> beatmap = default, Optional<ushort?> playlistOrder = default, Optional<int> ruleset = default)
Optional<int> ruleset = default)
{ {
return new PlaylistItem(beatmap.GetOr(Beatmap)) return new PlaylistItem(beatmap.GetOr(Beatmap))
{ {
@ -141,19 +139,19 @@ namespace osu.Game.Online.Rooms
PlayedAt = PlayedAt, PlayedAt = PlayedAt,
AllowedMods = AllowedMods, AllowedMods = AllowedMods,
RequiredMods = RequiredMods, RequiredMods = RequiredMods,
FreeStyle = FreeStyle,
valid = { Value = Valid.Value }, valid = { Value = Valid.Value },
BeatmapSetId = BeatmapSetId
}; };
} }
public bool Equals(PlaylistItem? other) public bool Equals(PlaylistItem? other)
=> ID == other?.ID => ID == other?.ID
&& Beatmap.OnlineID == other.Beatmap.OnlineID && Beatmap.OnlineID == other.Beatmap.OnlineID
&& BeatmapSetId == other.BeatmapSetId
&& RulesetID == other.RulesetID && RulesetID == other.RulesetID
&& Expired == other.Expired && Expired == other.Expired
&& PlaylistOrder == other.PlaylistOrder && PlaylistOrder == other.PlaylistOrder
&& AllowedMods.SequenceEqual(other.AllowedMods) && AllowedMods.SequenceEqual(other.AllowedMods)
&& RequiredMods.SequenceEqual(other.RequiredMods); && RequiredMods.SequenceEqual(other.RequiredMods)
&& FreeStyle == other.FreeStyle;
} }
} }

View File

@ -272,21 +272,9 @@ namespace osu.Game.Screens.OnlinePlay.Match
base.LoadComplete(); base.LoadComplete();
SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(OnSelectedItemChanged)); SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(OnSelectedItemChanged));
UserMods.BindValueChanged(_ => Scheduler.AddOnce(OnSelectedItemChanged));
UserMods.BindValueChanged(_ => Scheduler.AddOnce(updateMods)); UserBeatmap.BindValueChanged(_ => Scheduler.AddOnce(OnSelectedItemChanged));
UserRuleset.BindValueChanged(_ => Scheduler.AddOnce(OnSelectedItemChanged));
UserBeatmap.BindValueChanged(_ => Scheduler.AddOnce(() =>
{
updateBeatmap();
updateUserStyle();
}));
UserRuleset.BindValueChanged(_ => Scheduler.AddOnce(() =>
{
updateUserMods();
updateRuleset();
updateUserStyle();
}));
beatmapAvailabilityTracker.SelectedItem.BindTo(SelectedItem); beatmapAvailabilityTracker.SelectedItem.BindTo(SelectedItem);
beatmapAvailabilityTracker.Availability.BindValueChanged(_ => updateBeatmap()); beatmapAvailabilityTracker.Availability.BindValueChanged(_ => updateBeatmap());
@ -458,14 +446,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
if (!this.IsCurrentScreen() || SelectedItem.Value is not PlaylistItem item) if (!this.IsCurrentScreen() || SelectedItem.Value is not PlaylistItem item)
return; return;
// Reset user style if no longer valid.
// Todo: In the future this can be made more lenient, such as allowing a non-null ruleset as the set changes.
if (item.BeatmapSetId == null || item.BeatmapSetId != UserBeatmap.Value?.BeatmapSet!.OnlineID)
{
UserBeatmap.Value = null;
UserRuleset.Value = null;
}
updateUserMods(); updateUserMods();
updateBeatmap(); updateBeatmap();
updateMods(); updateMods();
@ -487,10 +467,10 @@ namespace osu.Game.Screens.OnlinePlay.Match
UserModsSelectOverlay.IsValidMod = m => allowedMods.Any(a => a.GetType() == m.GetType()); UserModsSelectOverlay.IsValidMod = m => allowedMods.Any(a => a.GetType() == m.GetType());
} }
if (item.BeatmapSetId == null) if (item.FreeStyle)
UserStyleSection?.Hide();
else
UserStyleSection?.Show(); UserStyleSection?.Show();
else
UserStyleSection?.Hide();
} }
private void updateUserMods() private void updateUserMods()
@ -499,8 +479,13 @@ namespace osu.Game.Screens.OnlinePlay.Match
return; return;
// Remove any user mods that are no longer allowed. // Remove any user mods that are no longer allowed.
var rulesetInstance = GetGameplayRuleset().CreateInstance(); Ruleset rulesetInstance = GetGameplayRuleset().CreateInstance();
var allowedMods = item.AllowedMods.Select(m => m.ToMod(rulesetInstance)); Mod[] allowedMods = item.AllowedMods.Select(m => m.ToMod(rulesetInstance)).ToArray();
Mod[] newUserMods = UserMods.Value.Where(m => allowedMods.Any(a => m.GetType() == a.GetType())).ToArray();
if (newUserMods.SequenceEqual(UserMods.Value))
return;
UserMods.Value = UserMods.Value.Where(m => allowedMods.Any(a => m.GetType() == a.GetType())).ToList(); UserMods.Value = UserMods.Value.Where(m => allowedMods.Any(a => m.GetType() == a.GetType())).ToList();
} }

View File

@ -83,11 +83,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
{ {
ID = itemToEdit?.ID ?? 0, ID = itemToEdit?.ID ?? 0,
BeatmapID = item.Beatmap.OnlineID, BeatmapID = item.Beatmap.OnlineID,
BeatmapSetID = item.BeatmapSetId,
BeatmapChecksum = item.Beatmap.MD5Hash, BeatmapChecksum = item.Beatmap.MD5Hash,
RulesetID = item.RulesetID, RulesetID = item.RulesetID,
RequiredMods = item.RequiredMods.ToArray(), RequiredMods = item.RequiredMods.ToArray(),
AllowedMods = item.AllowedMods.ToArray() AllowedMods = item.AllowedMods.ToArray(),
FreeStyle = item.FreeStyle
}; };
Task task = itemToEdit != null ? client.EditPlaylistItem(multiplayerItem) : client.AddPlaylistItem(multiplayerItem); Task task = itemToEdit != null ? client.EditPlaylistItem(multiplayerItem) : client.AddPlaylistItem(multiplayerItem);

View File

@ -403,7 +403,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
private void updateCurrentItem() private void updateCurrentItem()
{ {
Debug.Assert(client.Room != null); Debug.Assert(client.Room != null);
SelectedItem.Value = Room.Playlist.SingleOrDefault(i => i.ID == client.Room.Settings.PlaylistItemId); SelectedItem.Value = Room.Playlist.SingleOrDefault(i => i.ID == client.Room.Settings.PlaylistItemId);
UserBeatmap.Value = client.LocalUser?.BeatmapId == null ? null : UserBeatmap.Value;
UserRuleset.Value = client.LocalUser?.RulesetId == null ? null : UserRuleset.Value;
} }
private void handleRoomLost() => Schedule(() => private void handleRoomLost() => Schedule(() =>

View File

@ -111,8 +111,7 @@ namespace osu.Game.Screens.OnlinePlay
FreeMods.Value = initialItem.AllowedMods.Select(m => m.ToMod(rulesetInstance)).ToArray(); FreeMods.Value = initialItem.AllowedMods.Select(m => m.ToMod(rulesetInstance)).ToArray();
} }
if (initialItem.BeatmapSetId != null) FreeStyle.Value = initialItem.FreeStyle;
FreeStyle.Value = true;
} }
Mods.BindValueChanged(onModsChanged); Mods.BindValueChanged(onModsChanged);
@ -162,7 +161,7 @@ namespace osu.Game.Screens.OnlinePlay
RulesetID = Ruleset.Value.OnlineID, RulesetID = Ruleset.Value.OnlineID,
RequiredMods = Mods.Value.Select(m => new APIMod(m)).ToArray(), RequiredMods = Mods.Value.Select(m => new APIMod(m)).ToArray(),
AllowedMods = FreeMods.Value.Select(m => new APIMod(m)).ToArray(), AllowedMods = FreeMods.Value.Select(m => new APIMod(m)).ToArray(),
BeatmapSetId = FreeStyle.Value ? Beatmap.Value.BeatmapSetInfo.OnlineID : null FreeStyle = FreeStyle.Value
}; };
return SelectItem(item); return SelectItem(item);

View File

@ -63,6 +63,7 @@ namespace osu.Game.Screens.OnlinePlay
{ {
private readonly PlaylistItem item; private readonly PlaylistItem item;
private double itemLength; private double itemLength;
private int beatmapSetId;
public DifficultySelectFilterControl(PlaylistItem item) public DifficultySelectFilterControl(PlaylistItem item)
{ {
@ -72,8 +73,14 @@ namespace osu.Game.Screens.OnlinePlay
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(RealmAccess realm) private void load(RealmAccess realm)
{ {
int beatmapId = item.Beatmap.OnlineID; realm.Run(r =>
itemLength = realm.Run(r => r.All<BeatmapInfo>().FirstOrDefault(b => b.OnlineID == beatmapId)?.Length ?? 0); {
int beatmapId = item.Beatmap.OnlineID;
BeatmapInfo? beatmap = r.All<BeatmapInfo>().FirstOrDefault(b => b.OnlineID == beatmapId);
itemLength = beatmap?.Length ?? 0;
beatmapSetId = beatmap?.BeatmapSet?.OnlineID ?? 0;
});
} }
public override FilterCriteria CreateCriteria() public override FilterCriteria CreateCriteria()
@ -81,7 +88,7 @@ namespace osu.Game.Screens.OnlinePlay
var criteria = base.CreateCriteria(); var criteria = base.CreateCriteria();
// Must be from the same set as the playlist item. // Must be from the same set as the playlist item.
criteria.BeatmapSetId = item.BeatmapSetId; criteria.BeatmapSetId = beatmapSetId;
// Must be within 30s of the playlist item. // Must be within 30s of the playlist item.
criteria.Length.Min = itemLength - 30000; criteria.Length.Min = itemLength - 30000;

View File

@ -67,6 +67,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
{ {
base.LoadComplete(); base.LoadComplete();
SelectedItem.BindValueChanged(onSelectedItemChanged, true);
isIdle.BindValueChanged(_ => updatePollingRate(), true); isIdle.BindValueChanged(_ => updatePollingRate(), true);
Room.PropertyChanged += onRoomPropertyChanged; Room.PropertyChanged += onRoomPropertyChanged;
@ -75,6 +76,13 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
updateRoomPlaylist(); updateRoomPlaylist();
} }
private void onSelectedItemChanged(ValueChangedEvent<PlaylistItem?> item)
{
// Simplest for now.
UserBeatmap.Value = null;
UserRuleset.Value = null;
}
private void onRoomPropertyChanged(object? sender, PropertyChangedEventArgs e) private void onRoomPropertyChanged(object? sender, PropertyChangedEventArgs e)
{ {
switch (e.PropertyName) switch (e.PropertyName)

View File

@ -37,10 +37,10 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
private PlaylistItem createNewItem() => new PlaylistItem(Beatmap.Value.BeatmapInfo) private PlaylistItem createNewItem() => new PlaylistItem(Beatmap.Value.BeatmapInfo)
{ {
ID = room.Playlist.Count == 0 ? 0 : room.Playlist.Max(p => p.ID) + 1, ID = room.Playlist.Count == 0 ? 0 : room.Playlist.Max(p => p.ID) + 1,
BeatmapSetId = FreeStyle.Value ? Beatmap.Value.BeatmapSetInfo.OnlineID : null,
RulesetID = Ruleset.Value.OnlineID, RulesetID = Ruleset.Value.OnlineID,
RequiredMods = Mods.Value.Select(m => new APIMod(m)).ToArray(), RequiredMods = Mods.Value.Select(m => new APIMod(m)).ToArray(),
AllowedMods = FreeMods.Value.Select(m => new APIMod(m)).ToArray(), AllowedMods = FreeMods.Value.Select(m => new APIMod(m)).ToArray(),
FreeStyle = FreeStyle.Value
}; };
} }
} }