mirror of
https://github.com/ppy/osu.git
synced 2026-05-16 19:23:11 +08:00
Emit important replay frames on every judgement
- Closes https://github.com/ppy/osu/issues/4287 - Probably closes https://github.com/ppy/osu/issues/25405 (but not retroactively) Up until now, whether or not a replay frame is emitted depended solely on the user's input, i.e. mouse movement or key presses/releases. This, intersected with the replay playback system which is given allowance to perform interpolation between replay frames, leads to potential situations wherein a replay can play inaccurately when a judgement takes place without user input meaningfully changing. One such case is slider ends with their 36ms of judgement leniency; see https://github.com/ppy/osu/issues/25405#issuecomment-2879031106 for details on that. To that end, this commit aims to counteract that issue by *forcing* an important replay frame to be emitted on every new judgement recorded during gameplay. This will only benefit rulesets wherein judgements can occur that are not inherently tied to user input changing, which are going to be osu! as mentioned above, and maybe possibly catch. I don't foresee this doing anything relevant for taiko or mania.
This commit is contained in:
@@ -300,6 +300,7 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
if (score == null)
|
||||
{
|
||||
NewResult -= emitImportantFrame;
|
||||
recordingInputManager.Recorder = null;
|
||||
return;
|
||||
}
|
||||
@@ -311,7 +312,10 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
recorder.ScreenSpaceToGamefield = Playfield.ScreenSpaceToGamefield;
|
||||
|
||||
NewResult += emitImportantFrame;
|
||||
recordingInputManager.Recorder = recorder;
|
||||
|
||||
void emitImportantFrame(JudgementResult judgementResult) => recordingInputManager.Recorder?.RecordFrame(true);
|
||||
}
|
||||
|
||||
public override void SetReplayScore(Score replayScore)
|
||||
|
||||
@@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
public interface IHasRecordingHandler
|
||||
{
|
||||
public ReplayRecorder? Recorder { set; }
|
||||
public ReplayRecorder? Recorder { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,29 +51,29 @@ namespace osu.Game.Rulesets.UI
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
recordFrame(false);
|
||||
RecordFrame(false);
|
||||
}
|
||||
|
||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||
{
|
||||
recordFrame(false);
|
||||
RecordFrame(false);
|
||||
return base.OnMouseMove(e);
|
||||
}
|
||||
|
||||
public bool OnPressed(KeyBindingPressEvent<T> e)
|
||||
{
|
||||
pressedActions.Add(e.Action);
|
||||
recordFrame(true);
|
||||
RecordFrame(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnReleased(KeyBindingReleaseEvent<T> e)
|
||||
{
|
||||
pressedActions.Remove(e.Action);
|
||||
recordFrame(true);
|
||||
RecordFrame(true);
|
||||
}
|
||||
|
||||
private void recordFrame(bool important)
|
||||
public override void RecordFrame(bool important)
|
||||
{
|
||||
var last = target.Replay.Frames.LastOrDefault();
|
||||
|
||||
@@ -98,5 +98,7 @@ namespace osu.Game.Rulesets.UI
|
||||
public abstract partial class ReplayRecorder : Component
|
||||
{
|
||||
public Func<Vector2, Vector2> ScreenSpaceToGamefield;
|
||||
|
||||
public abstract void RecordFrame(bool important);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
public ReplayRecorder? Recorder
|
||||
{
|
||||
get => recorder;
|
||||
set
|
||||
{
|
||||
if (value == recorder)
|
||||
|
||||
Reference in New Issue
Block a user