things/enemies/ExploderElite.cs

Enemy class ExploderElite, a subtype of Exploder. It configures stats, movement and explosion behavior based on game difficulty, adjusts forces when damaged by bullets, and customizes animation/playback rates during its explode sequence.

Networking
using System;
using Sandbox;

public class ExploderElite : Exploder
{
	public override EnemyType EnemyType => EnemyType.ExploderElite;
	public override float GetMaxHealth()
	{
		switch ( Manager.Instance.Difficulty )
		{
			case 0: default: return 70f;
			case 1: return 72f;
			case 2: return 75f;
		}
	}

	public override Vector3 SpawnScale => new Vector3( 1.3f );

	public override bool CanHaveTarget => !IsStunned;
	public override bool CanMove => !IsStunned;
	public override bool CanTurn => !IsStunned;

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

		CoinValueMin = 4;
		CoinValueMax = 6;
		CoinChance = 1f;

		PushStrength = 1500f;
		Weight = 1.55f;

		_personalExplosionRadius = 80f;
		_personalExplodeTime = 5f;

		_explodeAnim = "ExplodeAttack";

		// todo: never spawn foot gibs

		if ( IsProxy )
			return;

		DetectTargetRange = 600f;
		LoseTargetRange = 800f;
		LoseTargetTime = 5f;
		MeleeDamage = Utils.Select( Manager.Instance.Difficulty, 11f, 12f, 13f );
		DamageTargetDelay = 0.7f;
		_personalTurnSpeed = Game.Random.Float( 3f, 4f );
		Acceleration = 120f * Utils.Select(Manager.Instance.Difficulty, 0.95f, 1f, 1.1f );
		AccelerationAttacking = 140f * Utils.Select(Manager.Instance.Difficulty, 0.95f, 1f, 1.15f );
		Deceleration = 2.4f;
		DecelerationAttacking = 2.2f;
	}

	protected override float GetMoveSpeedFactor()
	{
		return 1f;
	}

	protected override void Damage( float damage, Player player, DamageType damageType, Vector3 hitPos, Vector2 force, bool isCrit = false, bool shouldFlinch = true, DamageResultFlags damageFlags = DamageResultFlags.None )
	{
		base.Damage( damage, player, damageType, hitPos, force, isCrit, shouldFlinch, damageFlags );

		if ( IsProxy )
			return;

		if ( damageType == DamageType.Bullet )
		{
			var additionalForce = Utils.Map( force.Length, 10f, 300f, 100f, 200f ) * (IsDying ? 1.1f : 0.5f);
			ExplosionVelocity += force.Normal * additionalForce;
		}
	}

	protected override void StartDying( Vector2 dir, float force, Player player, DamageType damageType)
	{
		base.StartDying( dir, force, player, damageType );

		Acceleration = 180f;
		Deceleration = 0.9f;
		DecelerationAttacking = 0.9f;
	}

	protected override void HandleExplodingPlaybackRate( float explodeTime )
	{
		SetPlaybackRate( Utils.Map( _timeSinceExplodeStart, 0f, explodeTime, 1f, 3.5f, EasingType.QuadIn ) * AnimSpeedModifier );
	}
}