-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Change Taiko Classic HD, HR and HDHR to better match stable #27136
Open
vunyunt
wants to merge
19
commits into
ppy:master
Choose a base branch
from
vunyunt:taiko-classic
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
ecc98b5
Convert maximum and minimum aspect into bindable floats
vunyunt 34e888d
Match stable's nomod timerange on classic
vunyunt c75ce34
Classic hidden
vunyunt 01a3803
Classic hardrock
vunyunt 0fe6228
Implement classic hdhr
vunyunt b53a20b
Merge branch 'ppy:master' into taiko-classic
vunyunt 46b2c12
Fix codeinspect issues
vunyunt 5495523
Fix inaccurate comments
vunyunt 92ae6ca
Merge remote-tracking branch 'upstream/master' into taiko-classic
vunyunt 79cfcc8
Change TaikoPlayfieldAdjustmentContainer parameters to be protected i…
vunyunt 98f8fa2
Fix barline appearing before the beginning of playfield
vunyunt 67e86a8
Fix codeinspect issues
vunyunt e2bd8da
Fix InspectCode issue
vunyunt 8e052fe
Fix CurrentAspect not being set & revert barline fix
vunyunt 5c28597
Merge remote-tracking branch 'upstream/master' into taiko-classic
vunyunt a88b56a
Enable masking in bar line content container
vunyunt 02c9022
Merge remote-tracking branch 'upstream/master' into taiko-classic
vunyunt 8021f6b
Merge remote-tracking branch 'upstream/master' into taiko-classic
vunyunt 6c96f79
Implement NM fade-in
vunyunt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,11 @@ | ||
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using osu.Framework.Bindables; | ||
using osu.Framework.Graphics; | ||
using osu.Game.Rulesets.Mods; | ||
using osu.Game.Rulesets.Objects.Drawables; | ||
using osu.Game.Rulesets.Taiko.Objects; | ||
|
@@ -12,16 +17,143 @@ namespace osu.Game.Rulesets.Taiko.Mods | |
{ | ||
public class TaikoModClassic : ModClassic, IApplicableToDrawableRuleset<TaikoHitObject>, IApplicableToDrawableHitObject | ||
{ | ||
private DrawableTaikoRuleset drawableTaikoRuleset = null!; | ||
|
||
private TaikoPlayfieldAdjustmentContainer adjustmentContainer = null!; | ||
|
||
private IReadOnlyList<Mod> mods = Array.Empty<Mod>(); | ||
|
||
private const float hd_base_fade_out_duration = 0.375f; | ||
|
||
private const float hd_base_initial_alpha = 0.75f; | ||
|
||
private const float hdhr_base_fade_out_duration = 0.2f; | ||
|
||
private const float hdhr_base_initial_alpha = 0.2f; | ||
|
||
private const float hidden_base_aspect = 4f / 3f; | ||
|
||
/// <summary> | ||
/// Time range at which notes start to become visible in milliseconds. | ||
/// </summary> | ||
private const double nm_fade_in_time_range = 10000d / 1.4d; | ||
|
||
/// <summary> | ||
/// Duration notes take to fade in in milliseconds. | ||
/// </summary> | ||
private const float nm_fade_in_duration = 400f; | ||
|
||
/// <summary> | ||
/// Whether note fading in is enabled. | ||
/// </summary> | ||
private bool fadeInEnabled = true; | ||
|
||
private readonly BindableFloat hiddenFadeOutDuration = new BindableFloat(hd_base_fade_out_duration); | ||
|
||
private readonly BindableFloat hiddenInitialAlpha = new BindableFloat(hd_base_initial_alpha); | ||
|
||
public void ApplyToDrawableRuleset(DrawableRuleset<TaikoHitObject> drawableRuleset) | ||
{ | ||
var drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset; | ||
drawableTaikoRuleset.LockPlayfieldAspectRange.Value = false; | ||
drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset; | ||
adjustmentContainer = (TaikoPlayfieldAdjustmentContainer)drawableRuleset.PlayfieldAdjustmentContainer; | ||
|
||
// drawableRuleset.Mods should always be non-null here, but just in case. | ||
mods = drawableRuleset.Mods ?? mods; | ||
|
||
// Disable uppper bound for playfield aspect ratio | ||
// In stable, nomod time range is limited by fading notes in instead | ||
adjustmentContainer.MaximumAspect = float.PositiveInfinity; | ||
adjustmentContainer.MinimumAspect = 5f / 4f; | ||
|
||
TaikoModHidden? hidden = mods.OfType<TaikoModHidden>().FirstOrDefault(); | ||
|
||
if (mods.OfType<TaikoModHardRock>().Any()) | ||
{ | ||
// Hardrock disables note fading in | ||
fadeInEnabled = false; | ||
|
||
// For hardrock, the playfield time range is clamped to within classicMaxTimeRange and the equivalent | ||
// time range for a 16:10 aspect ratio. | ||
adjustmentContainer.TrimOnOverflow = false; | ||
|
||
// Apply stable aspect ratio limits for hardrock (visually taken) | ||
adjustmentContainer.MaximumAspect = 1.963f; | ||
|
||
// This is accurate to 4:3, but slightly off for 5:4 | ||
adjustmentContainer.MinimumAspect = 1.666f; | ||
|
||
adjustmentContainer.MinimumRelativeHeight = 0.26f; | ||
adjustmentContainer.MaximumRelativeHeight = 0.26f; | ||
|
||
if (hidden != null) | ||
{ | ||
hiddenInitialAlpha.BindTo(hidden.InitialAlpha); | ||
hiddenFadeOutDuration.BindTo(hidden.FadeOutDuration); | ||
drawableRuleset.OnUpdate += d => adjustHidden( | ||
hdhr_base_fade_out_duration, hdhr_base_initial_alpha, 16f / 9f, 0.8f); | ||
} | ||
} | ||
else if (hidden != null) | ||
{ | ||
// Hidden disables note fading in | ||
fadeInEnabled = false; | ||
|
||
// Stable limits the aspect ratio to 4:3 | ||
adjustmentContainer.MaximumAspect = hidden_base_aspect; | ||
|
||
// Enable playfield trimming for hidden | ||
adjustmentContainer.TrimOnOverflow = true; | ||
|
||
// Enable aspect ratio adjustment for hidden (see adjustHidden) | ||
hiddenInitialAlpha.BindTo(hidden.InitialAlpha); | ||
hiddenFadeOutDuration.BindTo(hidden.FadeOutDuration); | ||
drawableRuleset.OnUpdate += d => adjustHidden( | ||
hd_base_fade_out_duration, hd_base_initial_alpha, hidden_base_aspect); | ||
} | ||
} | ||
|
||
public void ApplyToDrawableHitObject(DrawableHitObject drawable) | ||
{ | ||
if (drawable is DrawableTaikoHitObject hit) | ||
{ | ||
hit.SnapJudgementLocation = true; | ||
|
||
if (fadeInEnabled) | ||
{ | ||
drawable.ApplyCustomUpdateState += fadeIn; | ||
} | ||
} | ||
} | ||
|
||
// Fade in notes with fixed duration. | ||
private void fadeIn(DrawableHitObject o, ArmedState state) | ||
{ | ||
double preempt = nm_fade_in_time_range / drawableTaikoRuleset.ControlPointAt(o.HitObject.StartTime).Multiplier; | ||
double start = o.HitObject.StartTime - preempt; | ||
o.Alpha = 0; | ||
|
||
using (o.BeginAbsoluteSequence(start)) | ||
{ | ||
o.FadeInFromZero(nm_fade_in_duration); | ||
} | ||
} | ||
|
||
// Adjust hidden initial alpha and fade out duration for different aspect ratios | ||
private void adjustHidden( | ||
float baseFadeOutDuration, | ||
float baseInitialAlpha, | ||
float baseAspect, | ||
float adjustmentRatio = 1f) | ||
{ | ||
float clampedAspect = adjustmentContainer.ClampedCurrentAspect; | ||
|
||
float fadeOutDurationAdjustment = clampedAspect / baseAspect - 1; | ||
fadeOutDurationAdjustment *= adjustmentRatio; | ||
hiddenFadeOutDuration.Value = baseFadeOutDuration + fadeOutDurationAdjustment; | ||
|
||
float initialAlphaAdjustment = clampedAspect / baseAspect - 1; | ||
initialAlphaAdjustment *= adjustmentRatio; | ||
hiddenInitialAlpha.Value = baseInitialAlpha + initialAlphaAdjustment; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using osu.Framework.Bindables; | ||
using osu.Framework.Graphics; | ||
using osu.Framework.Localisation; | ||
using osu.Game.Rulesets.Mods; | ||
|
@@ -29,7 +30,20 @@ public class TaikoModHidden : ModHidden, IApplicableToDrawableRuleset<TaikoHitOb | |
/// How long hitobjects take to fade out, in terms of the scrolling length. | ||
/// Range: [0, 1] | ||
/// </summary> | ||
private const float fade_out_duration = 0.375f; | ||
public readonly BindableFloat FadeOutDuration = new BindableFloat(0.375f) | ||
{ | ||
MinValue = 0f, | ||
MaxValue = 1f | ||
}; | ||
|
||
/// <summary> | ||
/// The initial alpha of hitobjects when they appear. | ||
/// </summary> | ||
public readonly BindableFloat InitialAlpha = new BindableFloat(1f) | ||
{ | ||
MinValue = 0f, | ||
MaxValue = 1f | ||
}; | ||
|
||
private DrawableTaikoRuleset drawableRuleset = null!; | ||
|
||
|
@@ -51,7 +65,8 @@ protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, | |
case DrawableHit: | ||
double preempt = drawableRuleset.TimeRange.Value / drawableRuleset.ControlPointAt(hitObject.HitObject.StartTime).Multiplier; | ||
double start = hitObject.HitObject.StartTime - preempt * fade_out_start_time; | ||
double duration = preempt * fade_out_duration; | ||
double duration = preempt * FadeOutDuration.Value; | ||
hitObject.Alpha = InitialAlpha.Value; | ||
|
||
using (hitObject.BeginAbsoluteSequence(start)) | ||
{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this setting gone, including the conditional in
Update()
depending on it? Doesn't this change behaviour of nomod?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was previously set to false in classic to disable aspect range limitations. With these changes playfield aspect range is always limited to some range and never fully unlocked
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe players wanted the unlock in the first place, which is why I'm not sure where this is coming from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With stable, time range is never fully unlocked:
(Note that these are purely from observations, in code they could be implemented differently)
Perhaps we can name this better - time range has been referred to in aspect ratio equivalents in the community, but it might be better to separate the two concepts here, especially with
trimOnOverflow
set totrue
, the effective time range and display aspect ratio can be decoupled. The issue with this is we are still expressing time range limits in aspect ratio equivalents in the code here, and I'm not sure if there's a better way to express them without introducing more arbitrary-seeming fractions or decimals