perks/PerkClickRemove.cs

PerkClickRemove is an Epic rarity perk that lets the player right-click to remove one level from another perk and drop a perk item. It tracks a click-remove count in the player's stats, updates UI display and plays UI sounds when activated.

Networking
using System;
using System.Numerics;
using Sandbox;

[Perk( Rarity.Epic, locked: true, alwaysOfferDebug: false )]
public class PerkClickRemove : Perk
{
	public override float ImportanceMultiplier => 0.1f;

	static PerkClickRemove()
	{
		Register<PerkClickRemove>(
			name: "Second Thoughts",
			imagePath: "textures/icons/vector/click_remove.png",

			// todo: should the amount say it's increasing each level?
			description: level => $"Right-click {level} of your perks\nto drop 1 level",
			upgradeDescription: level => $"Right-click {level - 1}→{level} of your perks\nto drop 1 level"
		);
	}

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

		HighlightColor = new Color( 1f, 0.7f, 0.6f );
		HighlightDuration = 0.25f;
		HighlightOpacity = 2f;
	}

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

		Player.Stats[PlayerStat.ClickRemovePerk] += 1f;
		ShouldUpdate = true;
		DisplayCooldown = 1f;
		DisplayText = $"{(int)Player.Stats[PlayerStat.ClickRemovePerk]}";
	}

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

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

		DisplayCooldownColor = new Color( 1f, 0.3f, 0.3f, Utils.Map( Utils.FastSin( RealTime.Now * 12f ), -1f, 1f, 0f, 1f ) );
	}

	public override void Remove( bool restart = false )
	{
		base.Remove( restart );

		Player.Stats[PlayerStat.ClickRemovePerk] = 0f;
	}

	public void Activate( TypeDescription type )
	{
		if ( !Player.HasPerk( type ) )
			return;

		if( type.TargetType == typeof( PerkClickRemove ) )
		{
			Manager.Instance.PlaySfxUI( "error2", pitch: Game.Random.Float(0.6f, 0.65f), volume: 0.95f );
			return;
		}

		var perkLevel = Player.GetPerkLevel( type );

		//Player.RemovePerk( type );
		Player.LevelDownPerk( type );

		//for(int i = 0; i < perkLevel; i++)
		Player.GivePerkItem( type, dir: Utils.GetRandomVectorInCone( -Player.FacingDir, coneDegrees: 90f) );

		Manager.Instance.PlaySfxUI( "click", pitch: 0.6f, volume: 0.75f );

		Player.Stats[PlayerStat.ClickRemovePerk] -= 1f;

		if( (int)Player.Stats[PlayerStat.ClickRemovePerk] <= 0 )
		{
			ShouldUpdate = false;
			DisplayCooldown = 0f;
			DisplayText = " ";
		}
		else
		{
			DisplayText = $"{(int)Player.Stats[PlayerStat.ClickRemovePerk]}";
		}

		Highlight();
	}
}