Skip to content

Commit

Permalink
Merge pull request #1282 from andy840119/refactor-singing-lyrics
Browse files Browse the repository at this point in the history
Refactor singing lyrics collect loglc.
  • Loading branch information
andy840119 authored Apr 23, 2022
2 parents 1fbc464 + 78f3f91 commit 6b0d4f5
Show file tree
Hide file tree
Showing 15 changed files with 133 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public KaraokeSessionStatics(KaraokeRulesetConfigManager config, IBeatmap beatma
SetDefault(KaraokeRulesetSession.PlaybackSpeed, overridePlaybackSpeed ? playbackSpeedValue : 0, -10, 10);

// Practice
SetDefault<Lyric>(KaraokeRulesetSession.NowLyric, null);
SetDefault<Lyric[]>(KaraokeRulesetSession.SingingLyrics, null);

// Saiten status
SetDefault(KaraokeRulesetSession.SaitenStatus, SaitenStatusMode.NotInitialized);
Expand Down Expand Up @@ -80,7 +80,7 @@ public enum KaraokeRulesetSession
PlaybackSpeed,

// Practice
NowLyric,
SingingLyrics,

// Saiten status
SaitenStatus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
if (beatmap.HitObjects.Count == 0)
return new KaraokeDifficultyAttributes { Mods = mods };

HitWindows hitWindows = new KaraokeHitWindows();
hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty);

return new KaraokeDifficultyAttributes
{
StarRating = skills[0].DifficultyValue() * star_scaling_factor,
Expand Down
11 changes: 0 additions & 11 deletions osu.Game.Rulesets.Karaoke/Judgements/KaraokeLyricJudgement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,8 @@ namespace osu.Game.Rulesets.Karaoke.Judgements
{
public class KaraokeLyricJudgement : KaraokeJudgement
{
public LyricTime Time { get; set; }

public override HitResult MaxResult => HitResult.Perfect;

protected override double HealthIncreaseFor(HitResult result) => 0;
}

public enum LyricTime
{
NotYet,

Available,

Exceed
}
}
37 changes: 13 additions & 24 deletions osu.Game.Rulesets.Karaoke/Objects/Drawables/DrawableLyric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,10 @@
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Karaoke.Configuration;
using osu.Game.Rulesets.Karaoke.Judgements;
using osu.Game.Rulesets.Karaoke.Scoring;
using osu.Game.Rulesets.Karaoke.Skinning.Default;
using osu.Game.Rulesets.Karaoke.Skinning.Elements;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
using osuTK;

Expand Down Expand Up @@ -46,10 +43,8 @@ public class DrawableLyric : DrawableKaraokeHitObject
private readonly IBindableList<int> singersBindable = new BindableList<int>();
private readonly BindableDictionary<CultureInfo, string> translateTextBindable = new();

/// <summary>
/// Invoked when a <see cref="JudgementResult"/> has been applied by this <see cref="DrawableHitObject"/> or a nested <see cref="DrawableHitObject"/>.
/// </summary>
public event Action<DrawableHitObject, JudgementResult> OnLyricStart;
public event Action<DrawableLyric> OnLyricStart;
public event Action<DrawableLyric> OnLyricEnd;

public new Lyric HitObject => (Lyric)base.HitObject;

Expand Down Expand Up @@ -208,26 +203,20 @@ private void applyTranslate()

protected override void CheckForResult(bool userTriggered, double timeOffset)
{
if (Result.Judgement is not KaraokeLyricJudgement judgement)
return;

double lyricStartOffset = timeOffset + HitObject.LyricDuration;

if (lyricStartOffset < 0)
{
judgement.Time = LyricTime.NotYet;
}
else if (!HitObject.HitWindows.CanBeHit(lyricStartOffset) && judgement.Time != LyricTime.Available)
if (timeOffset + HitObject.LyricDuration >= 0 && HitObject.HitWindows.CanBeHit(timeOffset + HitObject.LyricDuration))
{
// Apply start hit result
judgement.Time = LyricTime.Available;
OnLyricStart?.Invoke(this, Result);
// note: CheckForResult will not being triggered when roll-back the time.
// so there's no need to consider the case while roll-back.
OnLyricStart?.Invoke(this);
return;
}
else if (!HitObject.HitWindows.CanBeHit(timeOffset))

if (timeOffset >= 0 && HitObject.HitWindows.CanBeHit(timeOffset))
{
judgement.Time = LyricTime.Exceed;
OnLyricEnd?.Invoke(this);

// Apply end hit result
ApplyResult(r => { r.Type = HitResult.Meh; });
ApplyResult(r => { r.Type = KaraokeLyricHitWindows.DEFAULT_HIT_RESULT; });
}
}

Expand Down
4 changes: 0 additions & 4 deletions osu.Game.Rulesets.Karaoke/Objects/KaraokeHitObject.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Karaoke.Scoring;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Karaoke.Objects
{
public class KaraokeHitObject : HitObject
{
public double TimePreempt = 600;
public double TimeFadeIn = 400;

protected override HitWindows CreateHitWindows() => new KaraokeHitWindows();
}
}
4 changes: 4 additions & 0 deletions osu.Game.Rulesets.Karaoke/Objects/Lyric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
using osu.Game.Rulesets.Karaoke.Beatmaps;
using osu.Game.Rulesets.Karaoke.Judgements;
using osu.Game.Rulesets.Karaoke.Objects.Types;
using osu.Game.Rulesets.Karaoke.Scoring;
using osu.Game.Rulesets.Karaoke.Utils;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Karaoke.Objects
{
Expand Down Expand Up @@ -202,5 +204,7 @@ public void InitialWorkingTime()
StartTime = LyricStartTime;
Duration = LyricDuration;
}

protected override HitWindows CreateHitWindows() => new KaraokeLyricHitWindows();
}
}
4 changes: 4 additions & 0 deletions osu.Game.Rulesets.Karaoke/Objects/Note.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
using osu.Game.Rulesets.Karaoke.Configuration;
using osu.Game.Rulesets.Karaoke.Judgements;
using osu.Game.Rulesets.Karaoke.Objects.Types;
using osu.Game.Rulesets.Karaoke.Scoring;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Karaoke.Objects
{
Expand Down Expand Up @@ -100,5 +102,7 @@ public Lyric ParentLyric
}

public override Judgement CreateJudgement() => new KaraokeNoteJudgement();

protected override HitWindows CreateHitWindows() => new KaraokeNoteHitWindows();
}
}
23 changes: 1 addition & 22 deletions osu.Game.Rulesets.Karaoke/Scoring/KaraokeHitWindows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,7 @@

namespace osu.Game.Rulesets.Karaoke.Scoring
{
public class KaraokeHitWindows : HitWindows
public abstract class KaraokeHitWindows : HitWindows
{
private static readonly DifficultyRange[] karaoke_ranges =
{
new(HitResult.Perfect, 80, 50, 20),
new(HitResult.Meh, 80, 50, 20),
new(HitResult.Miss, 2000, 1500, 1000),
};

public override bool IsHitResultAllowed(HitResult result)
{
// In karaoke ruleset, time range is not the first thing.
return result switch
{
// Karaoke note hit result
HitResult.Perfect => true,
// Lyric hit result
HitResult.Meh => true,
_ => false
};
}

protected override DifficultyRange[] GetRanges() => karaoke_ranges;
}
}
26 changes: 26 additions & 0 deletions osu.Game.Rulesets.Karaoke/Scoring/KaraokeLyricHitWindows.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Karaoke.Scoring
{
public class KaraokeLyricHitWindows : KaraokeHitWindows
{
public const HitResult DEFAULT_HIT_RESULT = HitResult.Perfect;

private static readonly DifficultyRange[] lyric_ranges =
{
new(DEFAULT_HIT_RESULT, 40, 20, 10),
};

public override bool IsHitResultAllowed(HitResult result) =>
result switch
{
DEFAULT_HIT_RESULT => true,
_ => false
};

protected override DifficultyRange[] GetRanges() => lyric_ranges;
}
}
27 changes: 27 additions & 0 deletions osu.Game.Rulesets.Karaoke/Scoring/KaraokeNoteHitWindows.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Karaoke.Scoring
{
public class KaraokeNoteHitWindows : KaraokeHitWindows
{
private static readonly DifficultyRange[] karaoke_ranges =
{
new(HitResult.Perfect, 80, 50, 20),
new(HitResult.Meh, 80, 50, 20),
new(HitResult.Miss, 2000, 1500, 1000),
};

public override bool IsHitResultAllowed(HitResult result) =>
result switch
{
HitResult.Perfect => true,
HitResult.Meh => true,
_ => false
};

protected override DifficultyRange[] GetRanges() => karaoke_ranges;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ private Lyric createPreviewLyric()
Text = "karaoke"
},
},
HitWindows = new KaraokeHitWindows(),
HitWindows = new KaraokeLyricHitWindows(),
};

private IDictionary<CultureInfo, string> createPreviewTranslate(CultureInfo cultureInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ protected override void Update()
StartTime = startTime,
Duration = 1000,
Text = "Note",
HitWindows = new KaraokeHitWindows(),
HitWindows = new KaraokeNoteHitWindows(),
});

notePlayfield.Add(new BarLine
Expand Down
71 changes: 22 additions & 49 deletions osu.Game.Rulesets.Karaoke/UI/LyricPlayfield.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Caching;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Karaoke.Configuration;
using osu.Game.Rulesets.Karaoke.Judgements;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.Objects.Drawables;
using osu.Game.Rulesets.Objects;
Expand All @@ -20,69 +16,46 @@ namespace osu.Game.Rulesets.Karaoke.UI
{
public class LyricPlayfield : Playfield
{
[Resolved]
private IBindable<WorkingBeatmap> beatmap { get; set; }
private readonly Bindable<Lyric[]> singingLyrics = new();

public new IEnumerable<DrawableLyric> AllHitObjects => base.AllHitObjects.OfType<DrawableLyric>();

protected WorkingBeatmap WorkingBeatmap => beatmap.Value;

private readonly BindableDouble preemptTime = new();
private readonly Bindable<Lyric> nowLyric = new();
private readonly Cached seekCache = new();

public LyricPlayfield()
protected override void OnNewDrawableHitObject(DrawableHitObject drawableHitObject)
{
// Switch to target time
nowLyric.BindValueChanged(value =>
if (drawableHitObject is DrawableLyric drawableLyric)
{
if (!seekCache.IsValid || value.NewValue == null)
return;

double lyricStartTime = value.NewValue.LyricStartTime - preemptTime.Value;

WorkingBeatmap.Track.Seek(lyricStartTime);
});
drawableLyric.OnLyricStart += onLyricStart;
drawableLyric.OnLyricEnd += onLyricEnd;
}

seekCache.Validate();
base.OnNewDrawableHitObject(drawableHitObject);
}

protected override void LoadComplete()
private void onLyricStart(DrawableLyric drawableLyric)
{
base.LoadComplete();
var lyrics = singingLyrics.Value ?? Array.Empty<Lyric>();
var lyric = drawableLyric.HitObject;

NewResult += OnNewResult;
}

protected override void OnNewDrawableHitObject(DrawableHitObject drawableHitObject)
{
if (drawableHitObject is DrawableLyric drawableLyric)
{
// todo : not really sure should cancel binding action in here?
drawableLyric.OnLyricStart += OnNewResult;
}
if (lyrics.Contains(lyric))
return;

base.OnNewDrawableHitObject(drawableHitObject);
singingLyrics.Value = lyrics.Concat(new[] { lyric }).ToArray();
}

internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result)
private void onLyricEnd(DrawableLyric drawableLyric)
{
if (result.Judgement is not KaraokeLyricJudgement karaokeLyricJudgement)
var lyrics = singingLyrics.Value ?? Array.Empty<Lyric>();
var lyric = drawableLyric.HitObject;

if (!lyrics.Contains(lyric))
return;

// Update now lyric
var targetLyric = karaokeLyricJudgement.Time == LyricTime.Available ? judgedObject.HitObject as Lyric : null;
seekCache.Invalidate();
nowLyric.Value = targetLyric;
seekCache.Validate();
singingLyrics.Value = lyrics.Where(x => x != lyric).ToArray();
}

[BackgroundDependencyLoader]
private void load(KaraokeRulesetConfigManager rulesetConfig, KaraokeSessionStatics session)
private void load(KaraokeSessionStatics session)
{
// Practice
rulesetConfig.BindWith(KaraokeRulesetSetting.PracticePreemptTime, preemptTime);
session.BindWith(KaraokeRulesetSession.NowLyric, nowLyric);
session.BindWith(KaraokeRulesetSession.SingingLyrics, singingLyrics);

RegisterPool<Lyric, DrawableLyric>(50);
}
Expand Down
Loading

0 comments on commit 6b0d4f5

Please sign in to comment.