perks/PerkRerollFree.cs

A Perk class for a game, named PerkRerollFree. It grants a temporary free reroll period on player level-up, updates display cooldowns and visual/sound effects, and modifies a player stat for free reroll time.

Networking
using System;
using Sandbox;

[Perk( Rarity.Legendary, onlyUnpausedChoosing: false, locked: true, alwaysOfferDebug: false )]
public class PerkRerollFree : Perk
{
	private enum Mod { Time };

	private bool _needPlayEndSfx;

	static PerkRerollFree()
	{
		Register<PerkRerollFree>(
			name: "Speed Reader",
			imagePath: "textures/icons/vector/reroll_free.png",
			description: level => $"On level-up,\nrerolling is free for {GetValue( level, Mod.Time ).ToString( "0.#" )}s",
			upgradeDescription: level => $"On level-up,\nrerolling is free for {GetValue( level - 1, Mod.Time ).ToString("0.#")}→{GetValue( level, Mod.Time ).ToString("0.#")}s"
		);
	}

	public override void Start()
	{
		base.Start();
		DisplayCooldownColor = new Color( 0.8f, 0.4f, 1f, 3f );
	}

	public override void Refresh()
	{
		base.Refresh();

		// todo: make sure this still works in multiplayer, and is okay to use in singleplayer

		Player.Modify( this, PlayerStat.FreeRerollTime, GetValue( Level, Mod.Time ), ModifierType.Add );
	}

	private static float GetValue( int level, Mod mod, bool isPercent = false )
	{
		switch ( mod )
		{
			case Mod.Time:
			default:
				return 2f * level;
		}
	}

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

		DisplayCooldown = Utils.Map( Player.RealTimeSinceLvlUp, 0f, GetValue( Level, Mod.Time ), 1f, 0f );

		if ( _needPlayEndSfx && Player.RealTimeSinceLvlUp > GetValue( Level, Mod.Time ) )
		{
			_needPlayEndSfx = false;
			ShouldUpdate = false;

			if ( Player.IsChoosingLevelUpReward )
			{
				Manager.Instance.PlaySfxUI( "reroll", pitch: 0.8f, volume: 0.95f );

				HighlightColor = new Color( 1f, 0.4f, 0.4f );
				HighlightDuration = 0.25f;
				HighlightOpacity = 2f;
				Highlight();
			}

			DisplayText = " ";
			DisplayCooldown = 0f;
		}
	}

	public override void OnPlayerLevelUp()
	{
		base.OnPlayerLevelUp();

		_needPlayEndSfx = true;
		ShouldUpdate = true;

		Manager.Instance.PlaySfxUI( "reroll", pitch: 1.3f, volume: 1f );

		DisplayText = "FREE";

		HighlightColor = new Color( 0.4f, 0.4f, 1f );
		HighlightDuration = 0.3f;
		HighlightOpacity = 4f;
		Highlight();
	}
}