perks/PerkRandomExisting.cs

A Perk implementation called PerkRandomExisting that grants the player additional copies of perks they already have. It registers itself as a perk named "Specialization", tracks how many perk grants remain, and on Update attempts to give a random existing perk (excluding itself) after a short delay, showing a failure floater if none can be granted.

File Access
using System;
using Sandbox;

[Perk( Rarity.Uncommon, includedAtStart: false, alwaysOfferDebug: false )]
public class PerkRandomExisting : Perk
{
	private int _perkCount;
	private TimeSince _timeSincePerk;

	public override float ImportanceMultiplier => 0.15f;

	static PerkRandomExisting()
	{
		Register<PerkRandomExisting>(
			name: "Specialization",
			imagePath: "textures/icons/vector/random_existing_upgrade.png",
			description: level => $"+1 random perk you already have",
			upgradeDescription: level => $"+1 random perk you already have",
			tooltipInfo: "Won't give you a curse perk"
		);
	}

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

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

		ShouldUpdate = true;
		_perkCount++;
		_timeSincePerk = 0f;
	}

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

	}

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

		if ( _perkCount > 0 && _timeSincePerk > 0.2f )
		{
			if ( !Player.GiveRandomExistingPerk( ignoreType: typeof( PerkRandomExisting ) ) )
			//if ( !Player.GiveRandomExistingPerk( ignoreType: typeof( PerkRandomExisting ), showMessage: true, perkType: TypeLibrary.GetType( typeof( PerkRandomExisting ) ) ) )
			{
				//Player.PlaySfxUI( "error2", pitch: 0.55f, volume: 0.9f );
				//Manager.Instance.SpawnFloaterText( Player.WorldPosition.WithZ( 65f ), "ALREADY MAX!", new Color( 1f, 0.5f, 0.5f ), 1.3f, FloaterType.NegativeMessage );
				Manager.Instance.SpawnFloaterText( Player.WorldPosition.WithZ( 65f ), "FAILED!", new Color( 1f, 0.5f, 0.5f ), 1.3f, FloaterType.NegativeMessage );
			}

			_perkCount--;

			if ( _perkCount <= 0 )
				ShouldUpdate = false;
		}
	}
}