perks/PerkPerspective.cs

A Perk implementation named PerkPerspective. When leveled it grants the player a temporary perspective camera stat, spawns a number of random perks and one curse as perk items (queued and given over time), and toggles the manager orthographic camera state.

File Access
using System;
using Sandbox;

[Perk( Rarity.Unique, locked: true, minUnlocksReq: 3, alwaysOfferDebug: false )]
public class PerkPerspective : Perk
{
	private enum Mod { NumPerks };

	private TimeSince _timeSincePerk;
	private List<TypeDescription> _perkTypes = new();

	static PerkPerspective()
	{
		Register<PerkPerspective>(
			name: "New Perspective",
			imagePath: "textures/icons/vector/perspective.png",
			description: level => $"Stereo vision\n +{(int)GetValue(level, Mod.NumPerks)} random perks\n[-]+1[/-] curse"
		);
	}

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

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

		ShouldUpdate = true;
		_timeSincePerk = 0f;

		int numPerks = (int)GetValue( Level, Mod.NumPerks );

		List<TypeDescription> newPerks = new();
		for ( int i = 0; i < numPerks; i++ )
			newPerks.Add( Player.GetRandomPerkType() );

		List<TypeDescription> newCurses = new();
		for ( int i = 0; i < 1; i++ )
			newCurses.Add( Player.GetRandomPerkType( curseSelection: CurseSelection.OnlyCurses ) );

		var perkTokens = "";
		foreach ( var p in newPerks ) perkTokens += $" {Perk.GetRichTextToken( p )}";
		Manager.Instance.Chat.AddLocalChatMessage( $"{Perk.GetRichTextToken( GetType() )} Got {numPerks} random perks:{perkTokens}", from: "" );

		var curseTokens = "";
		foreach ( var p in newCurses ) curseTokens += $" {Perk.GetRichTextToken( p )}";
		Manager.Instance.Chat.AddLocalChatMessage( $"{Perk.GetRichTextToken( GetType() )} Got a curse:{curseTokens}", from: "" );

		_perkTypes.AddRange( newPerks );
		_perkTypes.AddRange( newCurses );
	}

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

		Player.Modify( this, PlayerStat.PerspectiveCamera, 1f, ModifierType.Add );

		Manager.Instance.SetOrthoCamera( false );
	}

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

		if ( _perkTypes.Count > 0 && _timeSincePerk > 0.33f )
		{
			var type = _perkTypes[0];
			var attrib = type.GetAttribute<PerkAttribute>();

			Player.GivePerkItem( type, dir: Utils.GetRandomVectorInCone( -Player.FacingDir ), forceToCollect: attrib.Curse );

			_perkTypes.RemoveAt( 0 );

			if ( _perkTypes.Count <= 0 )
				ShouldUpdate = false;

			_timeSincePerk = 0f;
		}
	}

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

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

		if ( !(Player.Stats[PlayerStat.PerspectiveCamera] > 0f) )
		{
			Manager.Instance.SetOrthoCamera( true );
			//Manager.Instance.Camera.OrthographicHeight = 500f;
		}
	}
}