10000 Reintroduce timing dependent HoldTails by LumpBloom7 · Pull Request #570 · LumpBloom7/sentakki · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Reintroduce timing dependent HoldTails #570

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

Merged
merged 3 commits into from
Apr 13, 2024
Merged
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
133 changes: 66 additions & 67 deletions osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableHold.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,10 @@ private void load()
});
}

protected override void OnFree()
protected override void OnApply()
{
base.OnFree();
HoldStartTime = null;
TotalHoldTime = 0;
base.OnApply();
isHolding = false;
}

protected override void UpdateInitialTransforms()
Expand All @@ -97,42 +96,62 @@ protected override void UpdateInitialTransforms()
.Then().Delay(HitObject.Duration - stretchTime) // Wait until the end of the hold note, while considering how much time we need for shrinking
.ResizeHeightTo(0, stretchTime); // We shrink the hold note as it exits

if (HoldStartTime == null && !Auto)
if (isHolding == false && !Auto)
NoteBody.Delay(animTime).FadeColour(Color4.Gray, 100);
}
}

protected override void CheckForResult(bool userTriggered, double timeOffset)
{
if (Time.Current > HitObject.GetEndTime())
if (!userTriggered)
{
endHold();
double totalHoldRatio = TotalHoldTime / ((IHasDuration)HitObject).Duration;
HitResult result;

if (totalHoldRatio >= .75 || Auto)
result = HitResult.Great;
else if (totalHoldRatio >= .5)
result = HitResult.Good;
else if (totalHoldRatio >= .25)
result = HitResult.Ok;
else
result = HitResult.Miss;

// This is specifically to accommodate the threshold setting in HR
if (!HitObject.HitWindows.IsHitResultAllowed(result))
result = HitResult.Miss;

// Hold is over, but head windows are still active.
// Only happens on super short holds
// Force a miss on the head in this case
if (!headContainer[0].Result.HasResult)
headContainer[0].MissForcefully();

ApplyResult(result);
if (timeOffset >= 0 && Auto)
ApplyResult(HitResult.Perfect);
else if (timeOffset >= 0 && isHolding)
ApplyResult(applyDeductionTo(HitResult.Perfect));
else if (!HitObject.HitWindows.CanBeHit(timeOffset: timeOffset))
ApplyResult(Result.Judgement.MinResult);

return;
}
var result = HitObject.HitWindows.ResultFor(timeOffset);

if (result == HitResult.None)
return;

if (HitObject.Ex && result.IsHit())
result = Result.Judgement.MaxResult;

ApplyResult(applyDeductionTo(result));

HitResult applyDeductionTo(HitResult originalResult)
{
int deduction = (int)Math.Min(Math.Floor(timeNotHeld / 300), 3);

var newResult = originalResult - deduction;

if (originalResult <= HitResult.Ok)
return HitResult.Ok;

return newResult;
}
}

private double timeNotHeld = 0;

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

if (!Head.AllJudged)
return;

if (isHolding)
return;

timeNotHeld += Time.Elapsed;
}

protected override void UpdateHitStateTransforms(ArmedState state)
{
base.UpdateHitStateTransforms(state);
Expand Down Expand Up @@ -190,33 +209,6 @@ protected override void ClearNestedHitObjects()
headContainer.Clear(false);
}

/// <summary>
/// Time at which the user started holding this hold note. Null if the user is not holding this hold note.
/// </summary>
public double? HoldStartTime { get; private set; }

public double TotalHoldTime;

private bool beginHoldAt(double timeOffset)
{
if (HoldStartTime is not null)
return false;

if (timeOffset < -Head.HitObject.HitWindows.WindowFor(HitResult.Miss))
return false;

HoldStartTime = Math.Max(Time.Current, HitObject.StartTime);
return true;
}

private void endHold()
{
if (HoldStartTime.HasValue)
TotalHoldTime += Math.Max(Time.Current - HoldStartTime.Value, 0);

HoldStartTime = null;
}

private SentakkiInputManager sentakkiActionInputManager = null!;
internal SentakkiInputManager SentakkiActionInputManager => sentakkiActionInputManager ??= (SentakkiInputManager)GetContainingInputManager();

Expand All @@ -235,6 +227,8 @@ private int pressedCount
}
}

private bool isHolding = false;

public bool OnPressed(KeyBindingPressEvent<SentakkiAction> e)
{
if (AllJudged)
Expand All @@ -243,21 +237,25 @@ public bool OnPressed(KeyBindingPressEvent<SentakkiAction> e)
if (e.Action != SentakkiAction.Key1 + HitObject.Lane)
return false;

if (beginHoldAt(Time.Current - Head.HitObject.StartTime))
{
Head.UpdateResult();
NoteBody.FadeColour(AccentColour.Value, 50);
return true;
}

// Passthrough excess inputs to later hitobjects in the same lane
return false;
if (isHolding)
return false;

double timeOffset = Time.Current - HitObject.StartTime;

if (timeOffset < -Head.HitObject.HitWindows.WindowFor(HitResult.Miss))
return false;

Head.UpdateResult();
isHolding = true;
NoteBody.FadeColour(AccentColour.Value, 50);
return true;
}

public void OnReleased(KeyBindingReleaseEvent<SentakkiAction> e)
{
if (AllJudged) return;
if (HoldStartTime is null) return;
if (!isHolding) return;

if (e.Action != SentakkiAction.Key1 + HitObject.Lane)
return;
Expand All @@ -267,7 +265,8 @@ public void OnReleased(KeyBindingReleaseEvent<SentakkiAction> e)
if (pressedCount > 1)
return;

endHold();
UpdateResult(true);
isHolding = false;

if (!AllJudged)
NoteBody.FadeColour(Color4.Gray, 100);
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Sentakki/Objects/Hold.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected override void CreateNestedHitObjects(CancellationToken cancellationTok
});
}

protected override HitWindows CreateHitWindows() => new SentakkiEmptyHitWindows();
protected override HitWindows CreateHitWindows() => new SentakkiTapHitWindows();

public class HoldHead : SentakkiLanedHitObject
{
Expand Down
Loading
0