Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Touch notes to have BREAK modifier #535

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public override void PostProcess()
{
Color4 noteColor = hitObject.DefaultNoteColour;

if (hitObject is SentakkiLanedHitObject laned && laned.Break)
if (hitObject is IBreakNote breakNote && breakNote.Break)
noteColor = breakColor;
else if (isTwin)
noteColor = twinColor;
Expand Down
3 changes: 2 additions & 1 deletion osu.Game.Rulesets.Sentakki/Mods/SentakkiModRelax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public class SentakkiModRelax : Mod, IApplicableAfterBeatmapConversion
public void ApplyToBeatmap(IBeatmap beatmap)
{
foreach (SentakkiHitObject ho in beatmap.HitObjects)
ho.Ex = true;
if (ho is IExNote exNote)
exNote.Ex = true;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Sentakki.Judgements;
using osu.Game.Rulesets.Sentakki.UI;
using osu.Game.Skinning;

namespace osu.Game.Rulesets.Sentakki.Objects.Drawables
{
Expand All @@ -25,7 +27,13 @@ public bool Auto
// Used for the animation update
protected readonly Bindable<double> AnimationDuration = new Bindable<double>(1000);

protected override float SamplePlaybackPosition => (Position.X / (SentakkiPlayfield.INTERSECTDISTANCE * 2)) + 0.5f;
protected override float SamplePlaybackPosition => Position.X / (SentakkiPlayfield.INTERSECTDISTANCE * 2);

private PausableSkinnableSound breakSample = null!;

private Container<DrawableScorePaddingObject> scorePaddingObjects = null!;

private Container<DrawableScoreBonusObject> scoreBonusObjects = null!;

public DrawableSentakkiHitObject()
: this(null)
Expand All @@ -37,6 +45,32 @@ public DrawableSentakkiHitObject(SentakkiHitObject? hitObject = null)
{
}

[BackgroundDependencyLoader]
private void load()
{
AddRangeInternal(new Drawable[]
{
scorePaddingObjects = new Container<DrawableScorePaddingObject>(),
scoreBonusObjects = new Container<DrawableScoreBonusObject>(),
breakSample = new PausableSkinnableSound(),
});
}

protected override void LoadSamples()
{
base.LoadSamples();

breakSample.Samples = HitObject.CreateBreakSample();
}

public override void PlaySamples()
{
base.PlaySamples();

breakSample.Balance.Value = CalculateSamplePlaybackBalance(SamplePlaybackPosition);
breakSample.Play();
}

[Resolved]
protected DrawableSentakkiRuleset? DrawableSentakkiRuleset { get; private set; }

Expand All @@ -52,7 +86,46 @@ protected override void OnApply()
{
base.OnApply();
AccentColour.BindTo(HitObject.ColourBindable);
ExBindable.BindTo(HitObject.ExBindable);
ExBindable.Value = (HitObject as IExNote)?.Ex ?? false;
}

protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
{
switch (hitObject)
{
case ScorePaddingObject p:
return new DrawableScorePaddingObject(p);

case ScoreBonusObject b:
return new DrawableScoreBonusObject(b);
}

return base.CreateNestedHitObject(hitObject);
}

protected override void AddNestedHitObject(DrawableHitObject hitObject)
{
switch (hitObject)
{
case DrawableScorePaddingObject p:
scorePaddingObjects.Add(p);
break;

case DrawableScoreBonusObject b:
scoreBonusObjects.Add(b);
break;

default:
base.AddNestedHitObject(hitObject);
break;
}
}

protected override void ClearNestedHitObjects()
{
base.ClearNestedHitObjects();
scorePaddingObjects.Clear(false);
scoreBonusObjects.Clear(false);
}

protected override JudgementResult CreateResult(Judgement judgement) => new SentakkiJudgementResult(HitObject, judgement);
Expand All @@ -70,14 +143,22 @@ protected new void ApplyResult(HitResult result)
SentakkiJudgementResult.Critical = false;
}

// Judge the scoreBonus
foreach (var bonusObject in scoreBonusObjects)
bonusObject.TriggerResult();

// Also give Break note score padding a judgement
for (int i = 0; i < scorePaddingObjects.Count; ++i)
scorePaddingObjects[^(i + 1)].ApplyResult(result);

base.ApplyResult(result);
}

protected override void OnFree()
{
base.OnFree();
AccentColour.UnbindFrom(HitObject.ColourBindable);
ExBindable.UnbindFrom(HitObject.ExBindable);
breakSample.ClearSamples();
}

protected override void Update()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Sentakki.UI;
using osu.Game.Skinning;

namespace osu.Game.Rulesets.Sentakki.Objects.Drawables
{
Expand All @@ -16,12 +15,6 @@ public partial class DrawableSentakkiLanedHitObject : DrawableSentakkiHitObject
protected override float SamplePlaybackPosition =>
(SentakkiExtensions.GetPositionAlongLane(SentakkiPlayfield.INTERSECTDISTANCE, HitObject.Lane).X / (SentakkiPlayfield.INTERSECTDISTANCE * 2)) + .5f;

private PausableSkinnableSound breakSample = null!;

private Container<DrawableScorePaddingObject> scorePaddingObjects = null!;

private Container<DrawableScoreBonusObject> scoreBonusObjects = null!;

public DrawableSentakkiLanedHitObject(SentakkiLanedHitObject? hitObject)
: base(hitObject)
{
Expand All @@ -30,88 +23,8 @@ public DrawableSentakkiLanedHitObject(SentakkiLanedHitObject? hitObject)
[BackgroundDependencyLoader]
private void load()
{
AddRangeInternal(new Drawable[]
{
scorePaddingObjects = new Container<DrawableScorePaddingObject>(),
scoreBonusObjects = new Container<DrawableScoreBonusObject>(),
breakSample = new PausableSkinnableSound(),
});

if (DrawableSentakkiRuleset is not null)
AnimationDuration.BindTo(DrawableSentakkiRuleset?.AdjustedAnimDuration);
}

protected override void LoadSamples()
{
base.LoadSamples();

breakSample.Samples = HitObject.CreateBreakSample();
}

public override void PlaySamples()
{
base.PlaySamples();

breakSample.Balance.Value = CalculateSamplePlaybackBalance(SamplePlaybackPosition);
breakSample.Play();
}

protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
{
switch (hitObject)
{
case ScorePaddingObject p:
return new DrawableScorePaddingObject(p);

case ScoreBonusObject b:
return new DrawableScoreBonusObject(b);
}

return base.CreateNestedHitObject(hitObject);
}

protected override void AddNestedHitObject(DrawableHitObject hitObject)
{
switch (hitObject)
{
case DrawableScorePaddingObject p:
scorePaddingObjects.Add(p);
break;

case DrawableScoreBonusObject b:
scoreBonusObjects.Add(b);
break;

default:
base.AddNestedHitObject(hitObject);
break;
}
}

protected override void ClearNestedHitObjects()
{
base.ClearNestedHitObjects();
scorePaddingObjects.Clear(false);
scoreBonusObjects.Clear(false);
}

protected override void OnFree()
{
base.OnFree();
breakSample.ClearSamples();
}

protected new void ApplyResult(HitResult hitResult)
{
// Judge the scoreBonus
foreach (var bonusObject in scoreBonusObjects)
bonusObject.TriggerResult();

// Also give Break note score padding a judgement
for (int i = 0; i < scorePaddingObjects.Count; ++i)
scorePaddingObjects[^(i + 1)].ApplyResult(hitResult);

base.ApplyResult(hitResult);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ protected override void CheckForResult(bool userTriggered, double timeOffset)
if (timeOffset < 0 && result is not HitResult.Perfect)
return;

if (result < HitResult.Perfect && ExBindable.Value && result.IsHit())
if (result < HitResult.Perfect && HitObject.Ex && result.IsHit())
result = Result.Judgement.MaxResult;

ApplyResult(result);
Expand Down
14 changes: 14 additions & 0 deletions osu.Game.Rulesets.Sentakki/Objects/IBreakNote.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using osu.Framework.Bindables;

namespace osu.Game.Rulesets.Sentakki.Objects;

public interface IBreakNote
{
virtual bool NeedBreakSample => true;

virtual int BreakScoreWeighting => 5;

BindableBool BreakBindable { get; }

bool Break { get; set; }
}
6 changes: 6 additions & 0 deletions osu.Game.Rulesets.Sentakki/Objects/IExNote.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace osu.Game.Rulesets.Sentakki.Objects;

public interface IExNote
{
bool Ex { get; set; }
}
Loading
Loading