perks/PerkDashPlayerReload.cs

An Epic perk class named Resupplier that triggers when the owner finishes a dash. It spawns a visual ring and sound, then instantly reloads other nearby alive players within a radius that scales with perk level and the player's radius multiplier.

NetworkingFile Access
using System;
using Sandbox;

[Perk( Rarity.Epic, multiplayerMode: MultiplayerMode.OnlyMultiplayer, locked: true, alwaysOfferDebug: false, IncludedCategories = new[] { PerkCategory.Aoe })]
public class PerkDashPlayerReload : Perk
{
	private enum Mod { Radius };


	static PerkDashPlayerReload()
	{
		Register<PerkDashPlayerReload>(
			name: "Resupplier",
			imagePath: "textures/icons/vector/dash_player_reload.png",
			description: level => $"Other players within {GetValue( level, Mod.Radius, true ).ToString( "0.##" )}m\nreload when you dash",
			upgradeDescription: level => $"Other players within {GetValue( level - 1, Mod.Radius, true ).ToString("0.##")}→{GetValue( level, Mod.Radius, true ).ToString("0.##")}m reload when you dash"
		);
	}

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

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

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

	}


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

		Vector2 pos = Player.Position2D;
		float radius = GetValue( Level, Mod.Radius ) * Player.Stats[PlayerStat.RadiusMultiplier];
		Manager.Instance.SpawnRingRpc( pos, radius, new Color( 0f, 0f, 0f, 0.5f ), 0.15f );

		Manager.Instance.PlaySfxNearby( "reload.start", Player.Position2D, pitch: Game.Random.Float( 1.4f, 1.5f ), volume: 1.3f, maxDist: 450f );

		foreach ( Player player in Manager.Instance.AlivePlayers )
		{
			if ( player == Player )
				continue;

			if ( (player.Position2D - pos).LengthSquared < MathF.Pow( radius, 2f ) )
			{
				player.ReloadInstantly();

				Highlight();
			}
		}
	}

	private static float GetValue( int level, Mod mod, bool isPercent = false )
	{
		switch ( mod )
		{
			case Mod.Radius:
			default:
				return (0.5f + 1f * level) * (isPercent ? 1f : Utils.Meter2Unit);
		}
	}
}