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

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

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

    }

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

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

		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 = 1.5f * Player.Stats[PlayerStat.RadiusMultiplier];
		float damage = GetDamageForLevel(Level) * Player.GetDamageMultiplier();
		var force = Utils.Map( Level, 1, 7, 2f, 5f, EasingType.SineIn );

		Manager.Instance.PlaySfxNearby( "shoot", Player.Position2D, pitch: 0.5f, volume: 0.6f, maxDist: 3f ); // todo

		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 = (thing.Position2D - Player.Position2D).LengthSquared;
				if ( dist_sqr < MathF.Pow( radius, 2f ) )
				{
					var addVel = (thing.Position2D - Player.Position2D).Normal * force;
					var addTempWeight = 0f;
					enemy.Damage( damage, Player, addVel, addTempWeight, false, DamageType.Ranged );
				}
			}
		}

		var explosion = Manager.Instance.SpawnExplosionEffect( Player.Position2D, new Color( 1f, 1f, 0f ), new Color( 1f, 1f, 0f ), opacity: 0.15f, scaleModifier: 0.75f * radius );
		explosion.Sprite.PlaybackSpeed = 4f;
		explosion.Lifetime = 0.25f;
	}

    public override string GetDescription(int newLevel)
	{
		return string.Format("When your shield breaks it deals {0} dmg to nearby enemies", GetDamageForLevel(Level));
	}

	public override string GetUpgradeDescription(int newLevel)
	{
		return newLevel > 1 ? string.Format( "When your shield breaks it deals {0}→{1} dmg to nearby enemies", GetDamageForLevel(newLevel - 1), GetDamageForLevel(newLevel)) : GetDescription(newLevel);
	}

	public float GetDamageForLevel(int level)
	{
		return 10 + 10 * level + (level == 5 ? 10 : 0);
	}
}