perks/PerkRerollTeleport.cs

A unique perk called "Panic Button" that grants reroll items and teleports the player after a reroll. It spawns up to 7 reroll items over time in a cone behind the player and teleports the player to a random position inside game bounds when a reroll completes.

NetworkingFile Access
using System;
using Sandbox;

[Perk( Rarity.Unique, alwaysOfferDebug: false )]
public class PerkRerollTeleport : Perk
{
	public override float ImportanceMultiplier => 0.6f;

	private int _numRerolls;
	private TimeSince _timeSinceItem;

	static PerkRerollTeleport()
	{
		Register<PerkRerollTeleport>(
			name: "Panic Button",
			imagePath: "textures/icons/vector/reroll_teleport.png",
			description: level => $"+7 reroll-item\nTeleport to a random location\nwhen you reroll"
		);
	}

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

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

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

		_numRerolls += 7;
		_timeSinceItem = 0f;
		ShouldUpdate = true;
	}

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

		if ( _numRerolls > 0 && _timeSinceItem > 0.15f )
		{
			var dir = Utils.GetRandomVectorInCone( -Player.FacingDir );
			Player.GiveItemRpc( "reroll_item", dir );
			_numRerolls--;

			Manager.Instance.PlaySfxNearbyRpc( "scuffle", Player.Position2D, pitch: Utils.Map( _numRerolls, 7, 1, 0.8f, 0.95f ), volume: 0.85f, maxDist: 300f );

			_timeSinceItem = 0f;

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

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

	}

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

		Vector2 targetPos = new Vector2( 
			Game.Random.Float( Manager.Instance.BOUNDS_MIN.x, Manager.Instance.BOUNDS_MAX.x ), 
			Game.Random.Float( Manager.Instance.BOUNDS_MIN.y, Manager.Instance.BOUNDS_MAX.y ) 
		);

		var useRealTime = !Manager.Instance.IsUnpausedChoosing;
		Player.Teleport( targetPos, useRealTime );

		Highlight();
	}
}