1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-14 23:33:23 +08:00

Merge branch 'master' into android

This commit is contained in:
tangalbert919 2019-01-06 00:06:56 -06:00
commit 4da5ca02eb
17 changed files with 110 additions and 37 deletions

View File

@ -7,6 +7,7 @@ using osu.Game.Rulesets.Objects.Types;
using System.Collections.Generic;
using osu.Game.Rulesets.Objects;
using System.Linq;
using osu.Framework.Caching;
using osu.Framework.Configuration;
using osu.Game.Audio;
using osu.Game.Beatmaps;
@ -26,8 +27,11 @@ namespace osu.Game.Rulesets.Osu.Objects
public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity;
public double Duration => EndTime - StartTime;
private Cached<Vector2> endPositionCache;
public override Vector2 EndPosition => endPositionCache.IsValid ? endPositionCache.Value : endPositionCache.Value = Position + this.CurvePositionAt(1);
public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t);
public override Vector2 EndPosition => Position + this.CurvePositionAt(1);
public override int ComboIndex
{
@ -56,7 +60,11 @@ namespace osu.Game.Rulesets.Osu.Objects
public SliderPath Path
{
get => PathBindable.Value;
set => PathBindable.Value = value;
set
{
PathBindable.Value = value;
endPositionCache.Invalidate();
}
}
public double Distance => Path.Distance;
@ -73,6 +81,8 @@ namespace osu.Game.Rulesets.Osu.Objects
if (TailCircle != null)
TailCircle.Position = EndPosition;
endPositionCache.Invalidate();
}
}
@ -92,7 +102,17 @@ namespace osu.Game.Rulesets.Osu.Objects
public List<List<SampleInfo>> NodeSamples { get; set; } = new List<List<SampleInfo>>();
public int RepeatCount { get; set; }
private int repeatCount;
public int RepeatCount
{
get => repeatCount;
set
{
repeatCount = value;
endPositionCache.Invalidate();
}
}
/// <summary>
/// The length of one span of this <see cref="Slider"/>.
@ -169,7 +189,11 @@ namespace osu.Game.Rulesets.Osu.Objects
private void createTicks()
{
var length = Path.Distance;
// A very lenient maximum length of a slider for ticks to be generated.
// This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage.
const double max_length = 100000;
var length = Math.Min(max_length, Path.Distance);
var tickDistance = MathHelper.Clamp(TickDistance, 0, length);
if (tickDistance == 0) return;

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using osu.Framework.Extensions;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Scoring;
@ -72,5 +73,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
}
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement);
protected override HitWindows CreateHitWindows() => new OsuHitWindows();
}
}

View File

@ -71,6 +71,8 @@ namespace osu.Game.Tests.Visual
private class TestRoomManager : IRoomManager
{
public event Action RoomsUpdated;
public readonly BindableCollection<Room> Rooms = new BindableCollection<Room>();
IBindableCollection<Room> IRoomManager.Rooms => Rooms;

View File

@ -136,6 +136,8 @@ namespace osu.Game.Tests.Visual
public Func<Room, bool> CreateRequested;
public event Action RoomsUpdated;
public IBindableCollection<Room> Rooms { get; } = null;
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)

View File

@ -5,7 +5,6 @@ using System.ComponentModel;
using System.Linq;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual
@ -23,7 +22,7 @@ namespace osu.Game.Tests.Visual
// Reset the mods
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay));
return new ReplayPlayer(new Score { Replay = dummyRulesetContainer.Replay });
return new ReplayPlayer(dummyRulesetContainer.ReplayScore);
}
}
}

View File

@ -25,23 +25,26 @@ namespace osu.Game.Beatmaps.Drawables
protected override Drawable CreateDrawable(BeatmapInfo model)
{
Drawable drawable;
return new DelayedLoadUnloadWrapper(() => {
Drawable drawable;
var localBeatmap = beatmaps.GetWorkingBeatmap(model);
var localBeatmap = beatmaps.GetWorkingBeatmap(model);
if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null)
drawable = new BeatmapSetCover(model.BeatmapSet);
else
drawable = new BeatmapBackgroundSprite(localBeatmap);
if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null)
drawable = new BeatmapSetCover(model.BeatmapSet);
else
drawable = new BeatmapBackgroundSprite(localBeatmap);
drawable.RelativeSizeAxes = Axes.Both;
drawable.Anchor = Anchor.Centre;
drawable.Origin = Anchor.Centre;
drawable.FillMode = FillMode.Fill;
drawable.RelativeSizeAxes = Axes.Both;
drawable.Anchor = Anchor.Centre;
drawable.Origin = Anchor.Centre;
drawable.FillMode = FillMode.Fill;
drawable.OnLoadComplete = d => d.FadeInFromZero(400);
return drawable;
return drawable;
}, 500, 10000);
}
protected override double FadeDuration => 400;
protected override double FadeDuration => 0;
}
}

View File

@ -79,6 +79,12 @@ namespace osu.Game.Online.Multiplayer
set => MaxAttempts.Value = value;
}
/// <summary>
/// The position of this <see cref="Room"/> in the list. This is not read from or written to the API.
/// </summary>
[JsonIgnore]
public int Position = -1;
public void CopyFrom(Room other)
{
RoomID.Value = other.RoomID;
@ -103,6 +109,8 @@ namespace osu.Game.Online.Multiplayer
Playlist.AddRange(other.Playlist);
else if (other.Playlist.Count > 0)
Playlist.First().ID = other.Playlist.First().ID;
Position = other.Position;
}
public bool ShouldSerializeRoomID() => false;

View File

@ -396,11 +396,11 @@ namespace osu.Game.Overlays.Profile
infoTextLeft.NewLine();
infoTextLeft.AddText("Last seen ", lightText);
infoTextLeft.AddText(new DrawableDate(user.LastVisit.Value), boldItalic);
infoTextLeft.NewParagraph();
}
if (user.PlayStyle?.Length > 0)
{
infoTextLeft.NewParagraph();
infoTextLeft.AddText("Plays with ", lightText);
infoTextLeft.AddText(string.Join(", ", user.PlayStyle), boldItalic);
}

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mods
public override bool HasImplementation => GetType().GenericTypeArguments.Length == 0;
public virtual void ApplyToRulesetContainer(RulesetContainer<T> rulesetContainer) => rulesetContainer.SetReplay(CreateReplayScore(rulesetContainer.Beatmap)?.Replay);
public virtual void ApplyToRulesetContainer(RulesetContainer<T> rulesetContainer) => rulesetContainer.SetReplayScore(CreateReplayScore(rulesetContainer.Beatmap));
}
public abstract class ModAutoplay : Mod, IApplicableFailOverride

View File

@ -163,8 +163,6 @@ namespace osu.Game.Rulesets.Scoring
AllJudged?.Invoke();
}
private readonly Dictionary<HitResult, int> scoreResultCounts = new Dictionary<HitResult, int>();
/// <summary>
/// Retrieve a score populated with data for the current play this processor is responsible for.
/// </summary>
@ -180,9 +178,11 @@ namespace osu.Game.Rulesets.Scoring
var hitWindows = CreateHitWindows();
foreach (var result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r)))
score.Statistics[result] = scoreResultCounts.GetOrDefault(result);
score.Statistics[result] = GetStatistic(result);
}
protected abstract int GetStatistic(HitResult result);
public abstract double GetStandardisedScore();
}
@ -378,6 +378,8 @@ namespace osu.Game.Rulesets.Scoring
}
}
protected override int GetStatistic(HitResult result) => scoreResultCounts.GetOrDefault(result);
public override double GetStandardisedScore() => getScore(ScoringMode.Standardised);
protected override void Reset(bool storeResults)

View File

@ -22,6 +22,7 @@ using osu.Game.Overlays;
using osu.Game.Replays;
using osu.Game.Rulesets.Configuration;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.UI
{
@ -130,7 +131,7 @@ namespace osu.Game.Rulesets.UI
protected virtual ReplayInputHandler CreateReplayInputHandler(Replay replay) => null;
public Replay Replay { get; private set; }
public Score ReplayScore { get; private set; }
/// <summary>
/// Whether the game is paused. Used to block user input.
@ -140,14 +141,14 @@ namespace osu.Game.Rulesets.UI
/// <summary>
/// Sets a replay to be used, overriding local input.
/// </summary>
/// <param name="replay">The replay, null for local input.</param>
public virtual void SetReplay(Replay replay)
/// <param name="replayScore">The replay, null for local input.</param>
public virtual void SetReplayScore(Score replayScore)
{
if (ReplayInputManager == null)
throw new InvalidOperationException($"A {nameof(KeyBindingInputManager)} which supports replay loading is not available");
Replay = replay;
ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null;
ReplayScore = replayScore;
ReplayInputManager.ReplayInputHandler = replayScore != null ? CreateReplayInputHandler(replayScore.Replay) : null;
HasReplayLoaded.Value = ReplayInputManager.ReplayInputHandler != null;
}
@ -302,9 +303,9 @@ namespace osu.Game.Rulesets.UI
mod.ReadFromConfig(config);
}
public override void SetReplay(Replay replay)
public override void SetReplayScore(Score replayScore)
{
base.SetReplay(replay);
base.SetReplayScore(replayScore);
if (ReplayInputManager?.ReplayInputHandler != null)
ReplayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace;

View File

@ -10,6 +10,11 @@ namespace osu.Game.Screens.Multi
{
public interface IRoomManager
{
/// <summary>
/// Invoked when the <see cref="Room"/>s have been updated.
/// </summary>
event Action RoomsUpdated;
/// <summary>
/// All the active <see cref="Room"/>s.
/// </summary>

View File

@ -52,6 +52,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components
rooms.ItemsAdded += addRooms;
rooms.ItemsRemoved += removeRooms;
roomManager.RoomsUpdated += updateSorting;
addRooms(rooms);
}
@ -104,6 +106,12 @@ namespace osu.Game.Screens.Multi.Lounge.Components
}
}
private void updateSorting()
{
foreach (var room in roomFlow)
roomFlow.SetLayoutPosition(room, room.Room.Position);
}
private void selectRoom(Room room)
{
var drawable = roomFlow.FirstOrDefault(r => r.Room == room);
@ -115,5 +123,13 @@ namespace osu.Game.Screens.Multi.Lounge.Components
selectedRoom.Value = room;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (roomManager != null)
roomManager.RoomsUpdated -= updateSorting;
}
}
}

View File

@ -165,8 +165,8 @@ namespace osu.Game.Screens.Multi.Match.Components
TimeSpan.FromHours(12),
//TimeSpan.FromHours(16),
TimeSpan.FromHours(24),
//TimeSpan.FromDays(3),
//TimeSpan.FromDays(7)
TimeSpan.FromDays(3),
TimeSpan.FromDays(7)
}
}
},

View File

@ -19,6 +19,8 @@ namespace osu.Game.Screens.Multi
{
public class RoomManager : PollingComponent, IRoomManager
{
public event Action RoomsUpdated;
private readonly BindableCollection<Room> rooms = new BindableCollection<Room>();
public IBindableCollection<Room> Rooms => rooms;
@ -52,6 +54,8 @@ namespace osu.Game.Screens.Multi
update(room, result);
addRoom(room);
RoomsUpdated?.Invoke();
onSuccess?.Invoke(room);
};
@ -125,13 +129,17 @@ namespace osu.Game.Screens.Multi
rooms.Remove(r);
}
// Add new matches, or update existing
foreach (var r in result)
for (int i = 0; i < result.Count; i++)
{
var r = result[i];
r.Position = i;
update(r, r);
addRoom(r);
}
RoomsUpdated?.Invoke();
tcs.SetResult(true);
};

View File

@ -285,7 +285,7 @@ namespace osu.Game.Screens.Play
if (!IsCurrentScreen) return;
var score = CreateScore();
if (RulesetContainer.Replay == null)
if (RulesetContainer.ReplayScore == null)
scoreManager.Import(score, true);
Push(CreateResults(score));
@ -297,7 +297,7 @@ namespace osu.Game.Screens.Play
protected virtual ScoreInfo CreateScore()
{
var score = new ScoreInfo
var score = RulesetContainer.ReplayScore?.ScoreInfo ?? new ScoreInfo
{
Beatmap = Beatmap.Value.BeatmapInfo,
Ruleset = ruleset,

View File

@ -17,7 +17,7 @@ namespace osu.Game.Screens.Play
protected override void LoadComplete()
{
base.LoadComplete();
RulesetContainer.SetReplay(score.Replay);
RulesetContainer.SetReplayScore(score);
}
protected override ScoreInfo CreateScore() => score.ScoreInfo;