perks/PerkOnlyUniqueAndLegendary.cs

Perk definition class for a game perk named "Cursed Bazaar" that forces the player to only see Legendary and Unique perk choices until they pick one, applies very large rarity-increase modifiers, shows highlight effects, and grants a random perk item with a curse on refresh.

NetworkingFile Access
using Sandbox;

[Perk( Rarity.Legendary, locked: true, minUnlocksReq: 1, alwaysOfferDebug: false )]
public class PerkOnlyUniqueAndLegendary : Perk
{
	static PerkOnlyUniqueAndLegendary()
	{
		Register<PerkOnlyUniqueAndLegendary>(
			name: "Cursed Bazaar",
			imagePath: "textures/icons/vector/only_unique_and_legendary.png",
			description: level => $"Only see Legendary and\nUnique choices (until you choose)\n[-]+1[/-] curse"
		);
	}

	private bool _boostActive;
	private RealTimeSince _realTimeSinceFlash;

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

		ShouldUpdate = true;

		_boostActive = true;
		_realTimeSinceFlash = 0f;

		HighlightColor = new Color( 1f, 0.8f, 0.2f );
		HighlightDuration = 0.4f;
		HighlightOpacity = 1.5f;

		Player.GiveRandomPerkItemWithMessage( sourcePerkType: TypeLibrary.GetType( this.GetType() ), curseSelection: CurseSelection.OnlyCurses, forceToCollect: true );

		Player.Modify( this, PlayerStat.RarityIncreaseLegendary, 99999f, ModifierType.Add );
		Player.Modify( this, PlayerStat.RarityIncreaseUnique, 99999f, ModifierType.Add );
	}

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

		if ( _boostActive && _realTimeSinceFlash > 0.5f )
		{
			Highlight();
			_realTimeSinceFlash = 0f;
		}
	}

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

		if ( _boostActive )
		{
			_boostActive = false;
			Player.StopModifying( this, PlayerStat.RarityIncreaseLegendary );
			Player.StopModifying( this, PlayerStat.RarityIncreaseUnique );

			HighlightColor = new Color( 0.4f, 0.8f, 1f );
			HighlightDuration = 0.6f;
			HighlightOpacity = 4f;
			Highlight();

			IconScale = Game.Random.Float( 1.2f, 1.35f );
			IconAngleOffset = Game.Random.Float( 12f, 22f ) * (Game.Random.Int( 0, 1 ) == 0 ? -1f : 1f);
		}
	}
}