perks/CurseChooseIgniteFreeze.cs

A unique curse perk class called Fractured Self that triggers when the player chooses another perk. If the chosen perk is itself a curse it does nothing. If the player already has the chosen perk it ignites the player, otherwise it applies a freeze. It also sets visual highlight and icon randomization.

Native Interop
using Sandbox;
using System;
using System.Numerics;

[Perk( Rarity.Unique, curse: true, alwaysOfferDebug: false )]
public class CurseChooseIgniteFreeze : Perk
{
	static CurseChooseIgniteFreeze()
	{
		Register<CurseChooseIgniteFreeze>(
			name: "Fractured Self",
			imagePath: "textures/icons/vector/curse_choose_ignite_freeze.png",
			description: level => $"When choosing a perk,\nget ignited if you already have it or get frozen if you don't"
		);
	}

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

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

	}

	public override void OnChoosePerk( TypeDescription type )
	{
		base.OnChoosePerk( type );

		var attrib = type.GetAttribute<PerkAttribute>();
		bool isCurse = attrib.Curse;

		if ( isCurse )
			return;

		if ( Player.HasPerk( type ) )
		{
			Player.Ignite( playerSource: Player, enemySource: null, enemyType: EnemyType.None, damage: 3f, lifetime: 4.4f, spreadChance: 0.1f, canStack: false );

			HighlightColor = new Color( 1f, 0.5f, 0.5f );
			HighlightDuration = 1.1f;
			HighlightOpacity = 4f;
			Highlight();
		}
		else
		{
			Player.Freeze( playerSource: Player, enemySource: null, timeScale: 0.6f, lifetime: 2.75f );

			HighlightColor = new Color( 0.5f, 0.5f, 1f );
			HighlightDuration = 1.1f;
			HighlightOpacity = 4f;
			Highlight();
		}

		IconScale = Game.Random.Float( 1.2f, 1.3f );
		IconAngleOffset = Game.Random.Float( 10f, 20f ) * (Game.Random.Int( 0, 1 ) == 0 ? -1f : 1f);

		// todo: local chat message explaining what happened?
	}
}