Units/Volatile.cs
namespace PlanetMeat;

[Group( "Planet Meat - Units" ), Title( "Volatile" ), Icon( "crisis_alert" )]
public sealed class Volatile : Component, IAttackBlame, IEnemyAttackReceiver, ITargetableListener
{
	[Property] public int BaseDamage { get; set; } = 5;

	[Property] public string Ident { get; set; } = "";

	public Targeter Targeter => field ??= this.FindNearestUpwards<Targeter>();

	private float untilCheck = -1.0f;

	protected override void OnStart()
	{
		base.OnStart();
		if ( Targeter is not null )
			untilCheck = AutoWeapon.FAST_RECHECK;
		else
			Log.Warning( $"{this} is a Volatile with no Targeter" );
	}

	protected override void OnUpdate()
	{
		base.OnUpdate();
		if ( Agenda.Current.Phase != Agenda.Phases.Wave || Targeter.Status.Killed )
			return;

		if ( untilCheck > -0.01f )
		{
			untilCheck -= Time.Delta;
			if ( untilCheck <= 0.0f )
			{
				var targets = Targeter.NextTargets;
				if ( targets.Count == 0 )
					untilCheck = AutoWeapon.FAST_RECHECK;
				else
					Explode();
			}
		}
	}

	public void OnKilled() => Explode();

	private void Explode()
	{
		var status = Targeter.Status;
		var dmg = new DamageInfo( BaseDamage, status.GameObject, GameObject );
		if ( !Difficulty.Current.HasChallenge( "burster_safety" ) )
			dmg.SetFriendlyFire( true );
		dmg.Explode( this, Targeter.Range );

		if ( status is Targetable t )
			t.Instakill( dmg );
	}
}