things/enemies/ExploderSpecial.cs

An enemy subclass 'ExploderSpecial' that extends Exploder. It sets stats and visuals on awake, overrides movement targeting to weave around the player, and spawns multiple expanding shockwave effects with damage when it explodes.

NetworkingFile Access
using Sandbox;
using static Manager;

public class ExploderSpecial : Exploder
{
	private const float SHOCKWAVE_TOTAL_TIME = 3f;

	protected override void OnAwake()
	{
		base.OnAwake();

		Health = 150f;

		MaxHealth = Health;

		Radius = 0.3f;
		Scale = 1.3f;
		Sprite.LocalScale = new Vector3( Scale * Game.Random.Float( 1f - HeightVariance, 1f + HeightVariance ), Scale * Game.Random.Float( 1f - WidthVariance, 1f + WidthVariance ), 1f ) * Globals.SPRITE_SCALE;

		ShadowScale = 1.35f;
		ShadowSpriteDirty = true;

		MoveSpeed = 1.65f;
		MoveSpeedAttacking = 4.5f;
		AggroRange = 2f;

		PushStrength = 35f;

		CoinChance = 1f;
		CoinValueMin = 3;
		CoinValueMax = 7;

		ExplosionDamage = 50f;
	}

	//protected override void OnUpdate()
	//{
	//	base.OnUpdate();

	//	Gizmo.Draw.Color = Color.White;
	//	Gizmo.Draw.Text( $"Utils.FastSin( SpawnTime * 2f ) < 0.5f: {Utils.FastSin( SpawnTime * 2f ) < 0.5f}", new global::Transform( (Vector3)Position2D + new Vector3( 0f, -0.7f, 0f ) ) );
	//}

	protected override Vector2 GetTargetPos()
	{
		if( Target.IsValid() )
		{
			//if ( !IsAttacking )
			//	return Target.Position2D;

			if ( Utils.FastSin( TimeSinceSpawn * 2.4f ) < 0.5f )
				return Target.Position2D;
			else
				return (Position2D + Utils.GetPerpendicularVector(Position2D - Target.Position2D) * (Utils.FastSin( TimeSinceSpawn * 3.1f ) < 0f ? -1f : 1f));
		}

		return (IsCharmed ? Manager.Instance.Player.Position2D : Position2D);
	}

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

		SpawnShockwaveEffect( SHOCKWAVE_TOTAL_TIME, 100f, 0f, damage: 14f );
		SpawnShockwaveEffect( SHOCKWAVE_TOTAL_TIME * 0.45f, 99f, -0.1f );
		SpawnShockwaveEffect( SHOCKWAVE_TOTAL_TIME * 0.35f, 98f, -0.2f );
	}

	void SpawnShockwaveEffect( float lifetime, float depth, float scaleOffset, float damage = 0f )
	{
		var ring = Manager.Instance.SpawnRingEffect( Position2D, new Color( 1f, 0f, 0.5f ), new Color( 1f, 1f, 0f ), damage, opacity: 1f, scaleMin: 0f, scaleMax: 25f, depth );
		ring.Lifetime = lifetime;
		ring.ScaleLifetime = SHOCKWAVE_TOTAL_TIME;
		ring.ScaleOffset = scaleOffset;
	}
}