Enemy subclass MinibossZapper2, configures stats and behavior for a miniboss enemy variant. Overrides health, visuals, movement, laser aiming and damage behavior, and sets runtime parameters in OnStart.
using System;
using Sandbox;
public class MinibossZapper2 : MinibossZapper
{
public override EnemyType EnemyType => EnemyType.MinibossZapper2;
public override string GibFolder => "miniboss_zapper_2";
public override float OverrideGibChance => 1f;
public override int ExtraDeathBloodSprayAmount => 25;
public override float GetMaxHealth()
{
switch ( Manager.Instance.Difficulty )
{
case 0: default: return 550f;
case 1: return 600f;
case 2: return 625f;
case 3: return 670f;
}
}
private bool _clockwiseLaserRot;
private float _currRotSpeed;
public override float ParticleYPosOverride => 0.6f;
public override float StunParticleYPosOverride => 1.1f;
protected override float LaserWobbleAmplitude => 4f;
protected override float LaserWobbleAmplitude2 => 1.5f;
protected override float LaserWobbleSpeedMin => 4f;
protected override float LaserWobbleSpeedMax => 9f;
protected override void OnStart()
{
base.OnStart();
CoinValueMin = 9;
CoinValueMax = 18;
CoinChance = 1f;
PushStrength = 7000f;
Weight = 1.5f;
_personalSpeedScale = 1f;
_personalSpeedFreq = Game.Random.Float( 9f, 11f );
// todo: never spawn foot gibs
if ( IsProxy )
return;
AggroRange = 50f;
DetectTargetRange = 575f;
LoseTargetRange = 1000f;
LoseTargetTime = 6f;
MeleeDamage = Utils.Select( Manager.Instance.Difficulty, 10f, 12f, 13f );
LaserDamage = Utils.Select( Manager.Instance.Difficulty, 9f, 14f, 17f );
DamageTargetDelay = 0.55f;
_personalTurnSpeed = Game.Random.Float( 4f, 7f );
Acceleration = 140f * Utils.Select( Manager.Instance.Difficulty, 0.9f, 1f, 1.05f );
AccelerationAttacking = 160f * Utils.Select( Manager.Instance.Difficulty, 0.9f, 1f, 1.05f );
Deceleration = 2.2f;
DecelerationAttacking = 2f;
_shootDelayMin = 2f;
_shootDelayMax = 7f;
_shootDelayTimer = Game.Random.Float( _shootDelayMin, _shootDelayMax );
_shootRange = 600f;
_laserTotalTimeMin = 15f;
_laserTotalTimeMax = 30f;
_laserLengthTotal = 660f;
_clockwiseLaserRot = Game.Random.Int( 0, 1 ) == 0;
}
protected override void HandleAiming()
{
float minRotSpeed = Utils.Map( HpPercent, 1f, 0f, -4f, -8f );
float maxRotSpeed = Utils.Map( HpPercent, 1f, 0f, -35f, -50f );
_currRotSpeed = Utils.MapReturn( _timeSinceShoot, 0f, _laserTotalTime, minRotSpeed, maxRotSpeed, EasingType.QuadOut ) * (_clockwiseLaserRot ? -1f : 1f);
WorldRotation = Rotation.FromYaw( WorldRotation.Yaw() + _currRotSpeed * Time.Delta * TimeScale );
}
protected override void HurtPlayer( Player player, Vector2 hitPos, Vector2 dir )
{
dir = Utils.GetPerpendicularVector( dir ) * (_clockwiseLaserRot ? 1f : -1f);
var force = Utils.Map( Math.Abs( _currRotSpeed ), 4f, 50f, 30f, 300f );
var upwardAmount = Utils.Map( Math.Abs( _currRotSpeed ), 4f, 50f, 0.05f, 1f ) * Game.Random.Float( 0.75f, 1.25f );
player.DamageRpc( LaserDamage, DamageType.Laser, hitPos, dir, upwardAmount, force, ragdollForce: force * 0.01f, this, enemyType: this.EnemyType );
}
protected override Color GetLaserColor()
{
return new Color( 1f, 0f, 0.75f ).WithAlpha( 5f + Utils.FastSin( _timeSincePrepareShoot * 15f ) * 4f );
}
protected override void FinishShooting()
{
base.FinishShooting();
if ( IsProxy )
return;
if ( Game.Random.Float( 0f, 1f ) < 0.9f )
_clockwiseLaserRot = !_clockwiseLaserRot;
}
}