status/ShieldCharmStatus.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;

[Status(5, 0, 1f, 0, false, typeof( ShieldStatus ) )]
public class ShieldCharmStatus : Status
{
	public ShieldCharmStatus()
    {
		Title = "Charming Shield";
		IconPath = "textures/icons/shield_charm.png";
	}

	public override void Init(Player player)
	{
		base.Init(player);

    }

	public override void Refresh()
    {
		Description = GetDescription(Level);
        
    }

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

		List<Thing> nearbyThings = new List<Thing>();

		for ( int dx = -2; dx <= 2; dx++ )
			for ( int dy = -2; dy <= 2; dy++ )
				Manager.Instance.AddThingsInGridSquare( new Manager.GridSquare( Player.GridPos.x + dx, Player.GridPos.y + dy ), nearbyThings );

		float radius = GetRadiusForLevel(Level) * Player.Stats[PlayerStat.RadiusMultiplier];

		bool didCharm = false;

		foreach ( Thing thing in nearbyThings )
		{
			if ( thing is Enemy enemy && !enemy.IsDying && (!enemy.IsSpawning || enemy.TimeSinceSpawn > 0.75f) && !enemy.IgnoreCollision && !enemy.IsCharmed )
			{
				var dist_sqr = (enemy.Position2D - Player.Position2D).LengthSquared;
				if ( dist_sqr < MathF.Pow( radius, 2f ) )
				{
					enemy.Velocity += (thing.Position2D - Player.Position2D).Normal * Game.Random.Float(1f, 2f);
					enemy.Charm();
					didCharm = true;
				}
			}
		}

		if(didCharm)
			Manager.Instance.PlaySfxNearby( "charm", Player.Position2D, pitch: Game.Random.Float( 0.9f, 1.1f ), volume: 1.3f, maxDist: 5f );

		var explosion = Manager.Instance.SpawnExplosionEffect( Player.Position2D, Color.Magenta, Color.Magenta, opacity: 0.2f, scaleModifier: 0.75f * radius );
		explosion.Sprite.PlaybackSpeed = 3f;
		explosion.Lifetime = 0.4f;
	}

    public override string GetDescription(int newLevel)
	{
		return string.Format("When you gain a shield, charm enemies within {0} meters", GetRadiusForLevel(Level).ToString("F1"));
	}

	public override string GetUpgradeDescription(int newLevel)
	{
		return newLevel > 1 ? string.Format( "When you gain a shield, charm enemies within {0}→{1} meters", GetRadiusForLevel( newLevel - 1).ToString( "F1" ), GetRadiusForLevel( newLevel).ToString( "F1" ) ) : GetDescription(newLevel);
	}

	public float GetRadiusForLevel(int level)
	{
		return 0.9f + 0.2f * level;
	}
}