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

Merge remote-tracking branch 'refs/remotes/ppy/master' into beatmap-video

This commit is contained in:
Andrei Zavatski 2019-09-13 13:48:14 +03:00
commit fb9b25b786
8 changed files with 74 additions and 43 deletions

View File

@ -27,6 +27,8 @@ namespace osu.Game.Rulesets.Catch.Replays
protected Replay Replay; protected Replay Replay;
private CatchReplayFrame currentFrame;
public override Replay Generate() public override Replay Generate()
{ {
// todo: add support for HT DT // todo: add support for HT DT
@ -36,7 +38,7 @@ namespace osu.Game.Rulesets.Catch.Replays
double lastTime = 0; double lastTime = 0;
// Todo: Realistically this shouldn't be needed, but the first frame is skipped with the way replays are currently handled // Todo: Realistically this shouldn't be needed, but the first frame is skipped with the way replays are currently handled
Replay.Frames.Add(new CatchReplayFrame(-100000, lastPosition)); addFrame(-100000, lastPosition);
void moveToNext(CatchHitObject h) void moveToNext(CatchHitObject h)
{ {
@ -58,18 +60,18 @@ namespace osu.Game.Rulesets.Catch.Replays
{ {
//we are already in the correct range. //we are already in the correct range.
lastTime = h.StartTime; lastTime = h.StartTime;
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, lastPosition)); addFrame(h.StartTime, lastPosition);
return; return;
} }
if (impossibleJump) if (impossibleJump)
{ {
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X)); addFrame(h.StartTime, h.X);
} }
else if (h.HyperDash) else if (h.HyperDash)
{ {
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeAvailable, lastPosition)); addFrame(h.StartTime - timeAvailable, lastPosition);
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X)); addFrame(h.StartTime, h.X);
} }
else if (dashRequired) else if (dashRequired)
{ {
@ -81,16 +83,16 @@ namespace osu.Game.Rulesets.Catch.Replays
float midPosition = (float)Interpolation.Lerp(lastPosition, h.X, (float)timeAtDashSpeed / timeAvailable); float midPosition = (float)Interpolation.Lerp(lastPosition, h.X, (float)timeAtDashSpeed / timeAvailable);
//dash movement //dash movement
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeAvailable + 1, lastPosition, true)); addFrame(h.StartTime - timeAvailable + 1, lastPosition, true);
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeAvailable + timeAtDashSpeed, midPosition)); addFrame(h.StartTime - timeAvailable + timeAtDashSpeed, midPosition);
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X)); addFrame(h.StartTime, h.X);
} }
else else
{ {
double timeBefore = positionChange / movement_speed; double timeBefore = positionChange / movement_speed;
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeBefore, lastPosition)); addFrame(h.StartTime - timeBefore, lastPosition);
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X)); addFrame(h.StartTime, h.X);
} }
lastTime = h.StartTime; lastTime = h.StartTime;
@ -122,5 +124,12 @@ namespace osu.Game.Rulesets.Catch.Replays
return Replay; return Replay;
} }
private void addFrame(double time, float? position = null, bool dashing = false)
{
var last = currentFrame;
currentFrame = new CatchReplayFrame(time, position, dashing, last);
Replay.Frames.Add(currentFrame);
}
} }
} }

View File

@ -3,6 +3,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using osu.Framework.Input.StateChanges; using osu.Framework.Input.StateChanges;
using osu.Framework.MathUtils; using osu.Framework.MathUtils;
using osu.Game.Replays; using osu.Game.Replays;
@ -17,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Replays
{ {
} }
protected override bool IsImportant(CatchReplayFrame frame) => frame.Position > 0; protected override bool IsImportant(CatchReplayFrame frame) => frame.Actions.Any();
protected float? Position protected float? Position
{ {
@ -38,21 +39,11 @@ namespace osu.Game.Rulesets.Catch.Replays
{ {
if (!Position.HasValue) return new List<IInput>(); if (!Position.HasValue) return new List<IInput>();
var actions = new List<CatchAction>();
if (CurrentFrame.Dashing)
actions.Add(CatchAction.Dash);
if (Position.Value > CurrentFrame.Position)
actions.Add(CatchAction.MoveRight);
else if (Position.Value < CurrentFrame.Position)
actions.Add(CatchAction.MoveLeft);
return new List<IInput> return new List<IInput>
{ {
new CatchReplayState new CatchReplayState
{ {
PressedActions = actions, PressedActions = CurrentFrame?.Actions ?? new List<CatchAction>(),
CatcherX = Position.Value CatcherX = Position.Value
}, },
}; };

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Replays.Legacy; using osu.Game.Replays.Legacy;
using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Catch.UI;
@ -11,6 +12,8 @@ namespace osu.Game.Rulesets.Catch.Replays
{ {
public class CatchReplayFrame : ReplayFrame, IConvertibleReplayFrame public class CatchReplayFrame : ReplayFrame, IConvertibleReplayFrame
{ {
public List<CatchAction> Actions = new List<CatchAction>();
public float Position; public float Position;
public bool Dashing; public bool Dashing;
@ -18,17 +21,39 @@ namespace osu.Game.Rulesets.Catch.Replays
{ {
} }
public CatchReplayFrame(double time, float? position = null, bool dashing = false) public CatchReplayFrame(double time, float? position = null, bool dashing = false, CatchReplayFrame lastFrame = null)
: base(time) : base(time)
{ {
Position = position ?? -1; Position = position ?? -1;
Dashing = dashing; Dashing = dashing;
if (Dashing)
Actions.Add(CatchAction.Dash);
if (lastFrame != null)
{
if (Position > lastFrame.Position)
Actions.Add(CatchAction.MoveRight);
else if (Position < lastFrame.Position)
Actions.Add(CatchAction.MoveLeft);
}
} }
public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap) public void ConvertFrom(LegacyReplayFrame currentFrame, IBeatmap beatmap, LegacyReplayFrame lastFrame = null)
{ {
Position = legacyFrame.Position.X / CatchPlayfield.BASE_WIDTH; Position = currentFrame.Position.X / CatchPlayfield.BASE_WIDTH;
Dashing = legacyFrame.ButtonState == ReplayButtonState.Left1; Dashing = currentFrame.ButtonState == ReplayButtonState.Left1;
if (Dashing)
Actions.Add(CatchAction.Dash);
if (lastFrame != null)
{
if (currentFrame.Position.X > lastFrame.Position.X)
Actions.Add(CatchAction.MoveRight);
else if (currentFrame.Position.X < lastFrame.Position.X)
Actions.Add(CatchAction.MoveLeft);
}
} }
} }
} }

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.Replays
Actions.AddRange(actions); Actions.AddRange(actions);
} }
public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap) public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap, LegacyReplayFrame lastFrame = null)
{ {
// We don't need to fully convert, just create the converter // We don't need to fully convert, just create the converter
var converter = new ManiaBeatmapConverter(beatmap); var converter = new ManiaBeatmapConverter(beatmap);

View File

@ -26,11 +26,11 @@ namespace osu.Game.Rulesets.Osu.Replays
Actions.AddRange(actions); Actions.AddRange(actions);
} }
public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap) public void ConvertFrom(LegacyReplayFrame currentFrame, IBeatmap beatmap, LegacyReplayFrame lastFrame = null)
{ {
Position = legacyFrame.Position; Position = currentFrame.Position;
if (legacyFrame.MouseLeft) Actions.Add(OsuAction.LeftButton); if (currentFrame.MouseLeft) Actions.Add(OsuAction.LeftButton);
if (legacyFrame.MouseRight) Actions.Add(OsuAction.RightButton); if (currentFrame.MouseRight) Actions.Add(OsuAction.RightButton);
} }
} }
} }

View File

@ -23,12 +23,12 @@ namespace osu.Game.Rulesets.Taiko.Replays
Actions.AddRange(actions); Actions.AddRange(actions);
} }
public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap) public void ConvertFrom(LegacyReplayFrame currentFrame, IBeatmap beatmap, LegacyReplayFrame lastFrame = null)
{ {
if (legacyFrame.MouseRight1) Actions.Add(TaikoAction.LeftRim); if (currentFrame.MouseRight1) Actions.Add(TaikoAction.LeftRim);
if (legacyFrame.MouseRight2) Actions.Add(TaikoAction.RightRim); if (currentFrame.MouseRight2) Actions.Add(TaikoAction.RightRim);
if (legacyFrame.MouseLeft1) Actions.Add(TaikoAction.LeftCentre); if (currentFrame.MouseLeft1) Actions.Add(TaikoAction.LeftCentre);
if (legacyFrame.MouseLeft2) Actions.Add(TaikoAction.RightCentre); if (currentFrame.MouseLeft2) Actions.Add(TaikoAction.RightCentre);
} }
} }
} }

View File

@ -14,8 +14,9 @@ namespace osu.Game.Rulesets.Replays.Types
/// <summary> /// <summary>
/// Populates this <see cref="ReplayFrame"/> using values from a <see cref="LegacyReplayFrame"/>. /// Populates this <see cref="ReplayFrame"/> using values from a <see cref="LegacyReplayFrame"/>.
/// </summary> /// </summary>
/// <param name="legacyFrame">The <see cref="LegacyReplayFrame"/> to extract values from.</param> /// <param name="currentFrame">The <see cref="LegacyReplayFrame"/> to extract values from.</param>
/// <param name="beatmap">The beatmap.</param> /// <param name="beatmap">The beatmap.</param>
void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap); /// <param name="lastFrame">The last <see cref="LegacyReplayFrame"/>, used to fill in missing delta information. May be null.</param>
void ConvertFrom(LegacyReplayFrame currentFrame, IBeatmap beatmap, LegacyReplayFrame lastFrame = null);
} }
} }

View File

@ -218,6 +218,7 @@ namespace osu.Game.Scoring.Legacy
private void readLegacyReplay(Replay replay, StreamReader reader) private void readLegacyReplay(Replay replay, StreamReader reader)
{ {
float lastTime = 0; float lastTime = 0;
LegacyReplayFrame currentFrame = null;
foreach (var l in reader.ReadToEnd().Split(',')) foreach (var l in reader.ReadToEnd().Split(','))
{ {
@ -240,23 +241,27 @@ namespace osu.Game.Scoring.Legacy
if (diff < 0) if (diff < 0)
continue; continue;
replay.Frames.Add(convertFrame(new LegacyReplayFrame(lastTime, var lastFrame = currentFrame;
currentFrame = new LegacyReplayFrame(lastTime,
Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE), Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE),
Parsing.ParseFloat(split[2], Parsing.MAX_COORDINATE_VALUE), Parsing.ParseFloat(split[2], Parsing.MAX_COORDINATE_VALUE),
(ReplayButtonState)Parsing.ParseInt(split[3])))); (ReplayButtonState)Parsing.ParseInt(split[3]));
replay.Frames.Add(convertFrame(currentFrame, lastFrame));
} }
} }
private ReplayFrame convertFrame(LegacyReplayFrame legacyFrame) private ReplayFrame convertFrame(LegacyReplayFrame currentFrame, LegacyReplayFrame lastFrame)
{ {
var convertible = currentRuleset.CreateConvertibleReplayFrame(); var convertible = currentRuleset.CreateConvertibleReplayFrame();
if (convertible == null) if (convertible == null)
throw new InvalidOperationException($"Legacy replay cannot be converted for the ruleset: {currentRuleset.Description}"); throw new InvalidOperationException($"Legacy replay cannot be converted for the ruleset: {currentRuleset.Description}");
convertible.ConvertFrom(legacyFrame, currentBeatmap); convertible.ConvertFrom(currentFrame, currentBeatmap, lastFrame);
var frame = (ReplayFrame)convertible; var frame = (ReplayFrame)convertible;
frame.Time = legacyFrame.Time; frame.Time = currentFrame.Time;
return frame; return frame;
} }