things/enemies/ExploderElite.cs

An enemy subclass 'ExploderElite' that extends a base Exploder enemy. It configures stats, movement and explosion behavior based on difficulty and state, overrides health, spawn scale, movement permissions, damage handling, death transition and animation playback rate.

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 );
	}
}