perks/PerkDashUseAll.cs

A unique perk class called "Chain Dash" that gives the player +3 dashes and attempts to immediately chain another dash after a dash finishes if the player still has dashes, is on the ground, and not stunned. It queues a pending chain flag on dash end and performs the extra dash during Update using movement, velocity, or facing direction.

using System;
using Sandbox;

[Perk( Rarity.Unique, locked: true, alwaysOfferDebug: false )]
public class PerkDashUseAll : Perk
{
	static PerkDashUseAll()
	{
		Register<PerkDashUseAll>(
			name: "Chain Dash",
			imagePath: "textures/icons/vector/dash_use_all.png",
			description: level => "+3 dashes\nAfter dashing, try to dash again"
		);
	}

	private bool _pendingChainDash;

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

		Player.Modify( this, PlayerStat.NumDashes, 3, ModifierType.Add );

		ShouldUpdate = true;
	}

	public override void OnDashFinished( Vector2 dir )
	{
		base.OnDashFinished( dir );

		if ( Player.NumDashesAvailable > 0 && !Player.IsInTheAir && !Player.IsStunned )
		{
			_pendingChainDash = true;
		}
	}

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

		if ( _pendingChainDash )
		{
			_pendingChainDash = false;

			if ( Player.NumDashesAvailable > 0 && !Player.IsInTheAir && !Player.IsStunned )
			{
				Vector2 dashDir = Player.MoveVector.LengthSquared > 0f ? Player.MoveVector : (Player.Velocity.LengthSquared > 0.1f ? Player.Velocity.Normal : Player.FacingDir);
				Player.Dash( dashDir );
			}
		}
	}
}