A subclass of SpitterElite that configures an elite spitter enemy variant. It sets stats (health, scale, speed, shooting and teleport timings), customizes teleport and movement behavior, and spawns modified enemy bullets when shooting.
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" );
}
}
}