2021-07-28 10:21:08 +00: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.Audio.Track ;
using osu.Framework.Bindables ;
2021-07-30 07:10:20 +00:00
using osu.Framework.Graphics ;
2021-07-28 10:21:08 +00:00
using osu.Framework.Graphics.Sprites ;
2021-08-01 17:09:37 +00:00
using osu.Framework.Localisation ;
2021-07-28 10:21:08 +00:00
using osu.Game.Configuration ;
2021-08-01 17:09:37 +00:00
using osu.Game.Graphics.UserInterface ;
using osu.Game.Overlays.Settings ;
2021-07-28 10:21:08 +00:00
using osu.Game.Rulesets.Objects ;
2021-07-30 06:49:11 +00:00
using osu.Game.Rulesets.Scoring ;
2021-07-28 10:21:08 +00:00
using osu.Game.Rulesets.UI ;
2021-07-30 06:49:11 +00:00
using osu.Game.Scoring ;
2021-07-28 10:21:08 +00: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 ;
2021-07-29 06:41:47 +00:00
public override string Description = > "Can you still feel the rhythm without music?" ;
2021-07-28 10:21:08 +00:00
public override ModType Type = > ModType . Fun ;
public override double ScoreMultiplier = > 1 ;
}
2021-07-30 06:49:11 +00:00
public abstract class ModMuted < TObject > : ModMuted , IApplicableToDrawableRuleset < TObject > , IApplicableToTrack , IApplicableToScoreProcessor
2021-07-28 10:21:08 +00:00
where TObject : HitObject
{
2021-07-30 07:46:42 +00:00
private readonly BindableNumber < double > mainVolumeAdjust = new BindableDouble ( 0.5 ) ;
2021-07-30 06:49:11 +00:00
private readonly BindableNumber < double > metronomeVolumeAdjust = new BindableDouble ( 0.5 ) ;
private BindableNumber < int > currentCombo ;
2021-07-30 08:38:04 +00:00
[SettingSource("Enable metronome", "Add a metronome beat to help you keep track of the rhythm.")]
2021-07-28 10:21:08 +00:00
public BindableBool EnableMetronome { get ; } = new BindableBool
{
Default = true ,
Value = true
} ;
2021-08-01 17:09:37 +00:00
[SettingSource("Final volume at combo", "The combo count at which point the track reaches its final volume.", SettingControlType = typeof(SettingsSlider<int, MuteComboSlider>))]
2021-07-30 06:49:11 +00:00
public BindableInt MuteComboCount { get ; } = new BindableInt
{
Default = 100 ,
Value = 100 ,
MinValue = 0 ,
MaxValue = 500 ,
} ;
2021-07-30 07:10:10 +00:00
[SettingSource("Start muted", "Increase volume as combo builds.")]
public BindableBool InverseMuting { get ; } = new BindableBool
{
Default = false ,
Value = false
} ;
2021-07-30 07:46:42 +00:00
[SettingSource("Mute hit sounds", "Hit sounds are also muted alongside the track.")]
public BindableBool AffectsHitSounds { get ; } = new BindableBool
{
2021-07-30 08:38:04 +00:00
Default = true ,
Value = true
2021-07-30 07:46:42 +00:00
} ;
2021-08-01 17:59:29 +00:00
protected ModMuted ( )
{
InverseMuting . BindValueChanged ( i = > MuteComboCount . MinValue = i . NewValue ? 1 : 0 , true ) ;
}
2021-07-28 10:21:08 +00:00
public void ApplyToTrack ( ITrack track )
{
2021-07-30 07:46:42 +00:00
track . AddAdjustment ( AdjustableProperty . Volume , mainVolumeAdjust ) ;
2021-07-28 10:21:08 +00:00
}
public void ApplyToDrawableRuleset ( DrawableRuleset < TObject > drawableRuleset )
{
2021-07-30 10:38:43 +00:00
if ( EnableMetronome . Value )
2021-07-30 06:49:11 +00:00
{
2021-07-31 06:03:26 +00:00
Metronome metronome ;
drawableRuleset . Overlays . Add ( metronome = new Metronome ( drawableRuleset . Beatmap . HitObjects . First ( ) . StartTime ) ) ;
2021-07-30 06:49:11 +00:00
2021-07-31 06:03:26 +00:00
metronome . AddAdjustment ( AdjustableProperty . Volume , metronomeVolumeAdjust ) ;
2021-07-30 10:38:43 +00:00
}
2021-07-30 07:46:42 +00:00
if ( AffectsHitSounds . Value )
2021-07-31 06:05:54 +00:00
drawableRuleset . Audio . AddAdjustment ( AdjustableProperty . Volume , mainVolumeAdjust ) ;
2021-07-30 06:49:11 +00:00
}
public void ApplyToScoreProcessor ( ScoreProcessor scoreProcessor )
{
currentCombo = scoreProcessor . Combo . GetBoundCopy ( ) ;
currentCombo . BindValueChanged ( combo = >
{
2021-08-01 17:12:35 +00:00
double dimFactor = MuteComboCount . Value = = 0 ? 1 : ( double ) combo . NewValue / MuteComboCount . Value ;
2021-07-30 06:49:11 +00:00
2021-07-30 07:10:10 +00:00
if ( InverseMuting . Value )
dimFactor = 1 - dimFactor ;
2021-07-30 07:10:20 +00:00
2021-07-30 08:38:04 +00:00
scoreProcessor . TransformBindableTo ( metronomeVolumeAdjust , dimFactor , 500 , Easing . OutQuint ) ;
scoreProcessor . TransformBindableTo ( mainVolumeAdjust , 1 - dimFactor , 500 , Easing . OutQuint ) ;
2021-07-30 06:49:11 +00:00
} , true ) ;
2021-07-28 10:21:08 +00:00
}
2021-07-30 06:49:11 +00:00
public ScoreRank AdjustRank ( ScoreRank rank , double accuracy ) = > rank ;
2021-07-28 10:21:08 +00:00
}
2021-08-01 17:09:37 +00:00
public class MuteComboSlider : OsuSliderBar < int >
{
2021-08-01 17:59:51 +00:00
public override LocalisableString TooltipText = > Current . Value = = 0 ? "always muted" : base . TooltipText ;
2021-08-01 17:09:37 +00:00
}
2021-07-28 10:21:08 +00:00
}