status/DamageForSpeedStatus.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;

[Status( 7, 0, 1f, 0, false )]
public class DamageForSpeedStatus : Status
{
	public DamageForSpeedStatus()
	{
		Title = "Momentum";
		IconPath = "textures/icons/damage_for_speed.png";
	}

	public override void Init( Player player )
	{
		base.Init( player );

		ShouldUpdate = true;
	}

	public override void Refresh()
	{
		Description = GetDescription( Level );

		Player.Modify( this, PlayerStat.DamageForSpeed, GetAmountForLevel( Level ), ModifierType.Add );
	}

	public override void Update( float dt )
	{
		base.Update( dt );

		float dmg = Player.Stats[PlayerStat.DamageForSpeed] * Player.Velocity.Length;

		if ( Player.IsDashing )
			dmg += Player.Stats[PlayerStat.DamageForSpeed] * Player.DashVelocity.Length;

		if ( dmg > 0.09f )
			DataString = $"+{dmg.ToString( "F1" )}";
		else
			DataString = "";
	}

	public override string GetDescription( int newLevel )
	{
		return string.Format( "Bullets deal {0} more damage for each meter per second of your speed", GetPrintAmountForLevel( Level ) );
	}

	public override string GetUpgradeDescription( int newLevel )
	{
		return newLevel > 1 ? string.Format( "Bullets deal {0}→{1} more damage for each meter per second of your speed", GetPrintAmountForLevel( newLevel - 1 ), GetPrintAmountForLevel( newLevel ) ) : GetDescription( newLevel );
	}

	public float GetAmountForLevel( int level )
	{
		return (0.05f + level * 0.4f) + (level == 7 ? 0.1f : 0f);
	}

	public string GetPrintAmountForLevel( int level )
	{
		return string.Format( "{0:0.00}", GetAmountForLevel( level ) );
	}
}