2021-07-28 18:21:08 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq ;
using osu.Framework.Audio ;
using osu.Framework.Bindables ;
2021-07-30 15:10:20 +08:00
using osu.Framework.Graphics ;
2021-07-28 18:21:08 +08:00
using osu.Framework.Graphics.Sprites ;
2021-08-02 01:09:37 +08:00
using osu.Framework.Localisation ;
2021-07-28 18:21:08 +08:00
using osu.Game.Configuration ;
2021-08-02 01:09:37 +08:00
using osu.Game.Graphics.UserInterface ;
using osu.Game.Overlays.Settings ;
2021-07-28 18:21:08 +08:00
using osu.Game.Rulesets.Objects ;
2021-07-30 14:49:11 +08:00
using osu.Game.Rulesets.Scoring ;
2021-07-28 18:21:08 +08:00
using osu.Game.Rulesets.UI ;
2021-07-30 14:49:11 +08:00
using osu.Game.Scoring ;
2021-07-28 18:21:08 +08:00
namespace osu.Game.Rulesets.Mods
{
public abstract class ModMuted : Mod
{
public override string Name = > "Muted" ;
public override string Acronym = > "MU" ;
public override IconUsage ? Icon = > FontAwesome . Solid . VolumeMute ;
2022-08-11 03:54:48 +08:00
public override LocalisableString Description = > "Can you still feel the rhythm without music?" ;
2021-07-28 18:21:08 +08:00
public override ModType Type = > ModType . Fun ;
public override double ScoreMultiplier = > 1 ;
2024-01-31 21:59:35 +08:00
public override bool Ranked = > UsesDefaultConfiguration ;
2021-07-28 18:21:08 +08:00
}
2021-07-30 14:49:11 +08:00
public abstract class ModMuted < TObject > : ModMuted , IApplicableToDrawableRuleset < TObject > , IApplicableToTrack , IApplicableToScoreProcessor
2021-07-28 18:21:08 +08:00
where TObject : HitObject
{
2021-07-30 15:46:42 +08:00
private readonly BindableNumber < double > mainVolumeAdjust = new BindableDouble ( 0.5 ) ;
2021-07-30 14:49:11 +08:00
private readonly BindableNumber < double > metronomeVolumeAdjust = new BindableDouble ( 0.5 ) ;
2022-07-10 23:16:51 +08:00
private readonly BindableNumber < int > currentCombo = new BindableInt ( ) ;
2021-07-30 14:49:11 +08:00
2022-11-25 00:15:11 +08:00
[SettingSource("Start muted", "Increase volume as combo builds.")]
public BindableBool InverseMuting { get ; } = new BindableBool ( ) ;
2021-07-30 16:38:04 +08:00
[SettingSource("Enable metronome", "Add a metronome beat to help you keep track of the rhythm.")]
2022-09-26 03:49:22 +08:00
public BindableBool EnableMetronome { get ; } = new BindableBool ( true ) ;
2021-07-28 18:21:08 +08:00
2021-08-02 01:09:37 +08:00
[SettingSource("Final volume at combo", "The combo count at which point the track reaches its final volume.", SettingControlType = typeof(SettingsSlider<int, MuteComboSlider>))]
2022-09-26 03:49:22 +08:00
public BindableInt MuteComboCount { get ; } = new BindableInt ( 100 )
2021-07-30 14:49:11 +08:00
{
MinValue = 0 ,
MaxValue = 500 ,
} ;
2021-07-30 15:46:42 +08:00
[SettingSource("Mute hit sounds", "Hit sounds are also muted alongside the track.")]
2022-09-26 03:49:22 +08:00
public BindableBool AffectsHitSounds { get ; } = new BindableBool ( true ) ;
2021-07-30 15:46:42 +08:00
2021-08-02 01:59:29 +08:00
protected ModMuted ( )
{
InverseMuting . BindValueChanged ( i = > MuteComboCount . MinValue = i . NewValue ? 1 : 0 , true ) ;
}
2022-05-10 23:01:15 +08:00
public void ApplyToTrack ( IAdjustableAudioComponent track )
2021-07-28 18:21:08 +08:00
{
2021-07-30 15:46:42 +08:00
track . AddAdjustment ( AdjustableProperty . Volume , mainVolumeAdjust ) ;
2021-07-28 18:21:08 +08:00
}
public void ApplyToDrawableRuleset ( DrawableRuleset < TObject > drawableRuleset )
{
2021-07-30 18:38:43 +08:00
if ( EnableMetronome . Value )
2021-07-30 14:49:11 +08:00
{
2022-05-20 16:12:35 +08:00
MetronomeBeat metronomeBeat ;
2021-07-31 14:03:26 +08:00
2023-02-21 18:04:06 +08:00
// Importantly, this is added to FrameStableComponents and not Overlays as the latter would cause it to be self-muted by the mod's volume adjustment.
drawableRuleset . FrameStableComponents . Add ( metronomeBeat = new MetronomeBeat ( drawableRuleset . Beatmap . HitObjects . First ( ) . StartTime ) ) ;
2021-07-30 14:49:11 +08:00
2022-05-20 16:12:35 +08:00
metronomeBeat . AddAdjustment ( AdjustableProperty . Volume , metronomeVolumeAdjust ) ;
2021-07-30 18:38:43 +08:00
}
2021-07-30 15:46:42 +08:00
if ( AffectsHitSounds . Value )
2021-07-31 14:05:54 +08:00
drawableRuleset . Audio . AddAdjustment ( AdjustableProperty . Volume , mainVolumeAdjust ) ;
2021-07-30 14:49:11 +08:00
}
public void ApplyToScoreProcessor ( ScoreProcessor scoreProcessor )
{
2022-07-10 23:16:51 +08:00
currentCombo . BindTo ( scoreProcessor . Combo ) ;
2021-07-30 14:49:11 +08:00
currentCombo . BindValueChanged ( combo = >
{
2021-08-02 01:12:35 +08:00
double dimFactor = MuteComboCount . Value = = 0 ? 1 : ( double ) combo . NewValue / MuteComboCount . Value ;
2021-07-30 14:49:11 +08:00
2021-07-30 15:10:10 +08:00
if ( InverseMuting . Value )
dimFactor = 1 - dimFactor ;
2021-07-30 15:10:20 +08:00
2021-07-30 16:38:04 +08:00
scoreProcessor . TransformBindableTo ( metronomeVolumeAdjust , dimFactor , 500 , Easing . OutQuint ) ;
scoreProcessor . TransformBindableTo ( mainVolumeAdjust , 1 - dimFactor , 500 , Easing . OutQuint ) ;
2021-07-30 14:49:11 +08:00
} , true ) ;
2021-07-28 18:21:08 +08:00
}
2021-07-30 14:49:11 +08:00
public ScoreRank AdjustRank ( ScoreRank rank , double accuracy ) = > rank ;
2021-07-28 18:21:08 +08:00
}
2021-08-02 01:09:37 +08:00
2023-02-03 00:24:45 +08:00
public partial class MuteComboSlider : RoundedSliderBar < int >
2021-08-02 01:09:37 +08:00
{
2021-08-02 01:59:51 +08:00
public override LocalisableString TooltipText = > Current . Value = = 0 ? "always muted" : base . TooltipText ;
2021-08-02 01:09:37 +08:00
}
2021-07-28 18:21:08 +08:00
}