things/enemies/SpitterEliteSpecial.cs
using Sandbox;
using System;
using System.Drawing;
using System.Runtime;

public class SpitterEliteSpecial : SpitterElite
{
	protected override void OnAwake()
	{
		base.OnAwake();

		Health = 235f;
		MaxHealth = Health;

		Radius = 0.3864f;
		Scale = 1.56f;
		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.40625f;
		ShadowSpriteDirty = true;

		ShootRange = 30f;

		PushStrength = 25f;
		MoveSpeedModifier = 0.6f;

		TELEPORT_DELAY_MIN = 40f;
		TELEPORT_DELAY_MAX = 165f;
		_nextTeleportDelay = Game.Random.Float( TELEPORT_DELAY_MIN, TELEPORT_DELAY_MAX );
		TeleportRequiredDist = 30f;

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

		SHOOT_DELAY_MIN = 4f;
	    SHOOT_DELAY_MAX = 12.5f;

		AggroRange = 1.5f;
	}

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

	//	Gizmo.Draw.Color = Color.White;
	//	Gizmo.Draw.Text( $"_timeSinceTeleported: {_timeSinceTeleported}\n_nextTeleportDelay: {_nextTeleportDelay}", new global::Transform( (Vector3)Position2D + new Vector3( 0f, -0.7f, 0f ) ) );
	//}

	protected override Vector2 GetTeleportPos()
	{
		return new Vector2( Game.Random.Float( Manager.Instance.BOUNDS_MIN_SPAWN.x, Manager.Instance.BOUNDS_MAX_SPAWN.x ), Game.Random.Float( Manager.Instance.BOUNDS_MIN_SPAWN.y, Manager.Instance.BOUNDS_MAX_SPAWN.y ) );
	}

	protected override void UpdateVelocity( Vector2 targetPos, float dt )
	{
		if(IsAttacking)
		{
			Velocity += (targetPos - Position2D).Normal * 4.8f * dt * (IsFeared ? -1f : 1f);
			return;
		}

		Velocity += (Position2D - targetPos).Normal * 1.0f * dt;
	}

	protected override void UpdateSprite( Thing target )
	{
		base.UpdateSprite( target );

		if( target.IsValid() && IsShooting )
		{
			FlipX = (target.Position2D.x > Position2D.x);
		}
	}

	public override void Shoot()
	{
		var target_pos = Target.IsValid() ? Target.Position2D + Target.Velocity * Game.Random.Float( 0.5f, 1.85f ) : Position2D + Utils.GetRandomVector() * 5f;
		var dir = Utils.RotateVector( (target_pos - Position2D).Normal, Game.Random.Float( -12f, 12f ) );
		//var enemyBullet = Manager.Instance.SpawnEnemyBullet( Position2D + new Vector2(0f, 0.55f) + dir * 0.03f, dir, speed: 2.15f );
		var enemyBullet = Manager.Instance.SpawnEnemyBullet( Position2D + dir * 0.03f, dir, speed: 9f );
		enemyBullet.SetColor( new Color( 0f, 0.6f, 0.6f ) );
		enemyBullet.Radius = 0.1f;
		enemyBullet.Sprite.LocalScale = enemyBullet.Sprite.LocalScale * 1.55f;
		enemyBullet.ShadowScale = 0.9f;
		enemyBullet.Damage = 5f;
		enemyBullet.Lifetime = 6f;

		if ( IsCharmed )
		{
			enemyBullet.Creator = this;
			enemyBullet.BecomeCharmed(elite: true);
		}

		Velocity *= 0.25f;
		_numVolleysShot++;
		_prepareShootTime = 0f;
		_currShootDelay = Game.Random.Float( 0.1f, 0.5f );

		Manager.Instance.PlaySfxNearby( "spitter.shoot", Position2D, pitch: Game.Random.Float( 1.0f, 1.1f ), volume: 0.9f, maxDist: 5f );

		if ( _numVolleysShot >= 3 )
		{
			Sprite.PlaybackSpeed = Game.Random.Float( 2f, 3f );
			Sprite.PlayAnimation( "shoot_reverse" );
		}
		else
		{
			Sprite.PlaybackSpeed = Game.Random.Float(4f, 6f);
			Sprite.PlayAnimation( "walk" );
			Sprite.PlayAnimation( "shoot" );
		}
	}
}