perks/PerkLevelUpHealthPack.cs

A Perk class that gives the player a health pack every N player level-ups. It tracks level-up count, calculates required levels from perk level, awards a "health_pack" item via Player.GiveItemRpc, and updates display and highlight visuals.

Networking
using System;
using Sandbox;

[Perk( Rarity.Mythic, alwaysOfferDebug: false )]
public class PerkLevelUpHealthPack : Perk
{
	private int _levelUpCount;

	private enum Mod { NumLevelsRequired };

	static PerkLevelUpHealthPack()
	{
		Register<PerkLevelUpHealthPack>(
			name: "Support Package",
			imagePath: "textures/icons/vector/level_up_health_pack.png",
			description: level => $"+1 healthpack every {(int)GetValue( level, Mod.NumLevelsRequired )} {(level == 3 ? "level-up" : "level-ups")}",
			upgradeDescription: level => $"+1 healthpack every {(int)GetValue( level - 1, Mod.NumLevelsRequired )}→{(int)GetValue( level, Mod.NumLevelsRequired )} {(level == 3 ? "level-up" : "level-ups")}"
		);
	}

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

		HighlightColor = new Color( 0.3f, 1f, 0.5f );
		HighlightDuration = 1f;
		HighlightOpacity = 2.5f;
	}

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

		Check();
	}

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

	}

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

		_levelUpCount++;
		Check();
	}

	void Check()
	{
		int numRequired = (int)GetValue( Level, Mod.NumLevelsRequired );
		if ( _levelUpCount >= numRequired )
		{
			Player.GiveItemRpc( "health_pack", Utils.GetRandomVectorInCone( -Player.FacingDir ) );
			_levelUpCount -= numRequired;
			Highlight();
		}

		DisplayText = $"{numRequired - _levelUpCount}";
	}

	private static float GetValue( int level, Mod mod, bool isPercent = false )
	{
		switch ( mod )
		{
			case Mod.NumLevelsRequired:
			default:
				return 5 - level;
		}
	}
}