2020-10-09 20:47:34 +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 ;
using osu.Framework.Utils ;
using osu.Game.Rulesets.Difficulty.Preprocessing ;
using osu.Game.Rulesets.Difficulty.Skills ;
using osu.Game.Rulesets.Mania.Difficulty.Preprocessing ;
2021-02-06 12:06:16 +08:00
using osu.Game.Rulesets.Mods ;
2020-10-09 20:47:34 +08:00
using osu.Game.Rulesets.Objects ;
namespace osu.Game.Rulesets.Mania.Difficulty.Skills
{
public class Strain : Skill
{
private const double individual_decay_base = 0.125 ;
private const double overall_decay_base = 0.30 ;
protected override double SkillMultiplier = > 1 ;
protected override double StrainDecayBase = > 1 ;
private readonly double [ ] holdEndTimes ;
private readonly double [ ] individualStrains ;
private double individualStrain ;
private double overallStrain ;
2021-02-06 12:06:16 +08:00
public Strain ( Mod [ ] mods , int totalColumns )
: base ( mods )
2020-10-09 20:47:34 +08:00
{
holdEndTimes = new double [ totalColumns ] ;
individualStrains = new double [ totalColumns ] ;
overallStrain = 1 ;
}
protected override double StrainValueOf ( DifficultyHitObject current )
{
var maniaCurrent = ( ManiaDifficultyHitObject ) current ;
var endTime = maniaCurrent . BaseObject . GetEndTime ( ) ;
var column = maniaCurrent . BaseObject . Column ;
double holdFactor = 1.0 ; // Factor to all additional strains in case something else is held
double holdAddition = 0 ; // Addition to the current note in case it's a hold and has to be released awkwardly
// Fill up the holdEndTimes array
for ( int i = 0 ; i < holdEndTimes . Length ; + + i )
{
// If there is at least one other overlapping end or note, then we get an addition, buuuuuut...
if ( Precision . DefinitelyBigger ( holdEndTimes [ i ] , maniaCurrent . BaseObject . StartTime , 1 ) & & Precision . DefinitelyBigger ( endTime , holdEndTimes [ i ] , 1 ) )
holdAddition = 1.0 ;
// ... this addition only is valid if there is _no_ other note with the same ending. Releasing multiple notes at the same time is just as easy as releasing 1
if ( Precision . AlmostEquals ( endTime , holdEndTimes [ i ] , 1 ) )
holdAddition = 0 ;
// We give a slight bonus to everything if something is held meanwhile
if ( Precision . DefinitelyBigger ( holdEndTimes [ i ] , endTime , 1 ) )
holdFactor = 1.25 ;
// Decay individual strains
individualStrains [ i ] = applyDecay ( individualStrains [ i ] , current . DeltaTime , individual_decay_base ) ;
}
holdEndTimes [ column ] = endTime ;
// Increase individual strain in own column
individualStrains [ column ] + = 2.0 * holdFactor ;
individualStrain = individualStrains [ column ] ;
overallStrain = applyDecay ( overallStrain , current . DeltaTime , overall_decay_base ) + ( 1 + holdAddition ) * holdFactor ;
return individualStrain + overallStrain - CurrentStrain ;
}
protected override double GetPeakStrain ( double offset )
2021-02-19 15:04:25 +08:00
= > applyDecay ( individualStrain , offset - Previous [ 0 ] . StartTime , individual_decay_base )
+ applyDecay ( overallStrain , offset - Previous [ 0 ] . StartTime , overall_decay_base ) ;
2020-10-09 20:47:34 +08:00
private double applyDecay ( double value , double deltaTime , double decayBase )
= > value * Math . Pow ( decayBase , deltaTime / 1000 ) ;
}
}