things/EnemySpikeElite.cs
using System;
using System.Collections.Generic;
using SpriteTools;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Manager;
public class EnemySpikeElite : Thing
{
public TimeSince SpawnTime { get; private set; }
public Enemy Shooter { get; set; }
public float Damage { get; set; }
public float Lifetime { get; set; }
public SpriteRendererLayer BgSprite { get; set; }
//public SpikeBackground Background { get; set; }
public List<Thing> _hitThings = new List<Thing>();
private bool _playedSfx;
public Thing Target { get; set; }
private float _speedMult;
public bool IsCharmed { get; private set; }
protected override void OnAwake()
{
base.OnAwake();
//OffsetY = -0.24f;
Radius = 0.43f;
Scale = 2.1f;
//Sprite.Size = new Vector2( 1f, 1f ) * Scale;
Sprite.SpriteFlags = Game.Random.Int( 0, 1 ) == 0 ? SpriteFlags.HorizontalFlip : SpriteFlags.None;
Sprite.LocalScale = new Vector3( 1f ) * Scale * Globals.SPRITE_SCALE;
Lifetime = 1.9f;
Damage = 24f;
SpawnTime = 0f;
// spawn background
var bgObj = Manager.Instance.EnemySpikeBgPrefab.Clone( WorldPosition );
bgObj.SetParent( GameObject );
//bgObj.Transform.LocalPosition = new Vector3( 0f, OffsetY, Globals.SHADOW_DEPTH_OFFSET );
bgObj.LocalPosition = new Vector3( 0f, 0f, Globals.SHADOW_DEPTH_OFFSET );
bgObj.NetworkMode = NetworkMode.Never;
BgSprite = bgObj.Components.Get<SpriteRendererLayer>();
BgSprite.SpriteFlags = Game.Random.Int( 0, 1 ) == 0 ? SpriteFlags.HorizontalFlip : SpriteFlags.None;
BgSprite.LocalScale = new Vector3( 1f ) * 2.2f * Globals.SPRITE_SCALE;
BgSprite.LocalRotation = new Angles( 0f, -90f, 0f );
if ( IsProxy )
return;
CollideWith.Add( typeof( Player ) );
CollideWith.Add( typeof( Enemy ) );
_speedMult = Game.Random.Float( 0.3f, 2.4f );
}
protected override void OnUpdate()
{
base.OnUpdate();
//Gizmo.Draw.Color = SpawnTime < 1.25f || SpawnTime > 1.6f ? Color.White.WithAlpha( 0.05f ) : Color.Red.WithAlpha( 0.1f );
//Gizmo.Draw.LineSphere( (Vector3)Position2D, Radius );
float dt = Time.Delta;
if ( Manager.Instance.Difficulty >= 1 && Target != null )
{
var speed = Utils.Map( SpawnTime, 0f, 0.7f, 3f, 0f, EasingType.SineIn ) * _speedMult;
if(Target.IsValid())
Velocity += ((Target.Position2D + Target.Velocity * Game.Random.Float( 0f, 2.5f )) - Position2D).Normal * speed * dt;
Position2D += Velocity * dt;
Position2D = Manager.Instance.ClampToBounds( Position2D );
var deceleration = Utils.Map( SpawnTime, 0.3f, 0.8f, 0.75f, 5f, EasingType.SineIn );
Velocity *= (1f - dt * deceleration);
}
WorldPosition = WorldPosition.WithZ( Globals.GetZPos( Position2D.y ) );
if ( SpawnTime > Lifetime )
{
Remove();
return;
}
if ( !Manager.Instance.ShouldUpdateThings )
return;
if ( !_playedSfx && SpawnTime > 1.15f )
{
Manager.Instance.PlaySfxNearby( "spike.thrust", Position2D, pitch: Game.Random.Float( 1.15f, 1.3f ), volume: 1.25f, maxDist: 6f );
_playedSfx = true;
}
for ( int dx = -1; dx <= 1; dx++ )
{
for ( int dy = -1; dy <= 1; dy++ )
{
Manager.Instance.HandleThingCollisionForGridSquare( this, new GridSquare( GridPos.x + dx, GridPos.y + dy ), dt );
if ( IsRemoved )
return;
}
}
}
public override void Colliding( Thing other, float percent, float dt )
{
base.Colliding( other, percent, dt );
if ( SpawnTime < 1.25f || SpawnTime > 1.6f )
return;
if ( other is Player player && !player.IsDead )
{
if ( _hitThings.Contains( player ) )
return;
float dmg = player.CheckDamageAmount( Damage, DamageType.Ranged );
if ( !player.IsInvulnerable && !player.IsTimePausedForChoosing )
{
Manager.Instance.PlaySfxNearby( "spike.stab", player.Position2D, pitch: Game.Random.Float( 0.85f, 0.9f ), volume: 1.6f, maxDist: 6f );
player.Damage( dmg );
player.AddVelocity( (player.Position2D - Position2D).Normal * Game.Random.Float(2f, 4f));
}
_hitThings.Add( player );
}
else if ( other is Enemy enemy && (IsCharmed != enemy.IsCharmed) )
{
if ( _hitThings.Contains( enemy ) )
return;
enemy.Damage( Damage, null, addVel: (enemy.Position2D - Position2D).Normal * Game.Random.Float( 1f, 2f ), addTempWeight: 0f, isCrit: false, DamageType.Ranged );
if ( Shooter.IsValid() )
enemy.Target = Shooter;
Manager.Instance.PlaySfxNearby( "spike.stab", enemy.Position2D, pitch: Game.Random.Float( 1.15f, 1.25f ), volume: 1.2f, maxDist: 4.5f );
_hitThings.Add( enemy );
}
}
public void BecomeCharmed( bool elite = false )
{
IsCharmed = true;
Sprite.Tint = new Color( 1f, 0f, 1f, 0.8f );
Sprite.FlashTint = new Color( 1f, 0f, 1f, 0.9f );
BgSprite.Tint = new Color( 1f, 0f, 1f, 0.6f );
Damage = 30f * Manager.Instance.Player.Stats[PlayerStat.CharmedEnemyDmgDealtMultiplier];
}
}